From 51af3e5069ee4cee30e2f929b48bef4e56940d7c Mon Sep 17 00:00:00 2001 From: Simon Pichugin Date: Nov 01 2018 16:39:12 +0000 Subject: Issue 49999 - Integrate React structure into cockpit-389-ds Description: Refactor the existing 389-console Cockpit plugin structure so it uses React, Babel, Eslint. Add Makefile targets and refactor spec-file accordingly. Add python3-policycoreutils, npm and nodejs to BuildRequires. Put blank Plugins page which work in React and uses Cockpit API. Reviewed by: mreynolds, vashirov, mhonek (Thanks!) https://pagure.io/389-ds-base/issue/49999 --- diff --git a/Makefile.am b/Makefile.am index 417febc..579f977 100644 --- a/Makefile.am +++ b/Makefile.am @@ -326,6 +326,7 @@ pkgconfigdir = $(libdir)/pkgconfig serverincdir = $(includedir)/@serverincdir@ gdbautoloaddir = $(prefixdir)/share/gdb/auto-load$(sbindir) cockpitdir = $(prefixdir)/share/cockpit@cockpitdir@ +metainfodir = $(prefixdir)/share/metainfo/389-console # This has to be hardcoded to /lib - $libdir changes between lib/lib64, but # sysctl.d is always in /lib. @@ -758,7 +759,9 @@ libexec_SCRIPTS = ldap/admin/src/scripts/ds_selinux_enabled \ install-data-hook: if [ "$(srcdir)" != "." ]; then cp -r $(srcdir)/src/cockpit src ; fi mkdir -p $(DESTDIR)$(cockpitdir) - rsync -rupE src/cockpit/389-console/ $(DESTDIR)$(cockpitdir) + rsync -rupE src/cockpit/389-console/cockpit_dist/ $(DESTDIR)$(cockpitdir) + mkdir -p $(DESTDIR)$(metainfodir) + rsync -up src/cockpit/389-console/org.cockpit-project.389-console.metainfo.xml $(DESTDIR)$(metainfodir)/org.cockpit-project.389-console.metainfo.xml if ENABLE_PERL sbin_SCRIPTS = ldap/admin/src/scripts/setup-ds.pl \ @@ -2378,6 +2381,24 @@ lib389: src/lib389/setup.py lib389-install: lib389 cd $(srcdir)/src/lib389; $(PYTHON) setup.py install --skip-build --force +node_modules: + cd $(srcdir)/src/cockpit/389-console; make -f node_modules.mk install + +# Cockpit UI plugin - we install the dependancies and build the JS sources +# and then we use install-data-hook for copying the results on 'make install' +389-console: node_modules + cd $(srcdir)/src/cockpit/389-console; make -f node_modules.mk build-cockpit-plugin + +# This requires a built source tree and avoids having to install anything system-wide +389-console-devel-install: + cd $(srcdir)/src/cockpit/389-console; \ + rm ~/.local/share/cockpit/389-console; \ + mkdir -p ~/.local/share/cockpit/; \ + ln -s `pwd`/dist ~/.local/share/cockpit/389-console + +389-console-clean: + cd $(srcdir)/src/cockpit/389-console; make -f node_modules.mk clean + # RPM-related tasks RPMBUILD ?= $(abs_builddir)/rpmbuild diff --git a/rpm.mk b/rpm.mk index a62a15d..1b3f7b3 100644 --- a/rpm.mk +++ b/rpm.mk @@ -31,13 +31,20 @@ clean: rm -rf dist rm -rf rpmbuild -local-archive: +node_modules: + cd src/cockpit/389-console; make -f node_modules.mk install + +cockpit_dist: node_modules + cd src/cockpit/389-console; make -f node_modules.mk build-cockpit-plugin + +local-archive: cockpit_dist -mkdir -p dist/$(NAME_VERSION) - rsync -a --exclude=dist --exclude=.git --exclude=rpmbuild . dist/$(NAME_VERSION) + rsync -a --exclude=node_modules --exclude=dist --exclude=.git --exclude=rpmbuild . dist/$(NAME_VERSION) tarballs: local-archive -mkdir -p dist/sources cd dist; tar cfj sources/$(TARBALL) $(NAME_VERSION) + cd src/cockpit/389-console; rm -rf dist rm -rf dist/$(NAME_VERSION) cd dist/sources ; \ if [ $(BUNDLE_JEMALLOC) -eq 1 ]; then \ diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in index 8c72b83..0ae388c 100644 --- a/rpm/389-ds-base.spec.in +++ b/rpm/389-ds-base.spec.in @@ -127,9 +127,12 @@ BuildRequires: python%{python3_pkgversion}-pyasn1-modules BuildRequires: python%{python3_pkgversion}-dateutil BuildRequires: python%{python3_pkgversion}-argcomplete BuildRequires: python%{python3_pkgversion}-argparse-manpage +BuildRequires: python%{python3_pkgversion}-policycoreutils # For cockpit BuildRequires: rsync +BuildRequires: npm +BuildRequires: nodejs # END BUILD REQUIRES # Now, attach the requires only to the package that needs them. @@ -380,7 +383,6 @@ autoreconf -fiv --enable-cmocka %if 0%{?rhel} > 7 || 0%{?fedora} - # lib389 pushd ./src/lib389 %py3_build @@ -818,6 +820,7 @@ exit 0 %{_mandir}/man8/dsidm.8.gz %files -n cockpit-389-ds -f cockpit.list +%{_datarootdir}/metainfo/389-console/org.cockpit-project.389-console.metainfo.xml %defattr(-,root,root,-) %doc README.md diff --git a/src/cockpit/389-console/.babelrc b/src/cockpit/389-console/.babelrc new file mode 100644 index 0000000..d0ef093 --- /dev/null +++ b/src/cockpit/389-console/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["@babel/env", + "@babel/preset-react"] +} diff --git a/src/cockpit/389-console/.eslintignore b/src/cockpit/389-console/.eslintignore new file mode 100644 index 0000000..8d87b1d --- /dev/null +++ b/src/cockpit/389-console/.eslintignore @@ -0,0 +1 @@ +node_modules/* diff --git a/src/cockpit/389-console/.eslintrc.json b/src/cockpit/389-console/.eslintrc.json new file mode 100644 index 0000000..3b7538e --- /dev/null +++ b/src/cockpit/389-console/.eslintrc.json @@ -0,0 +1,52 @@ +{ + "env": { + "browser": true, + "es6": true + }, + "extends": ["eslint:recommended", "standard", "standard-react"], + "parser": "babel-eslint", + "parserOptions": { + "ecmaFeatures": { + "experimentalObjectRestSpread": true, + "jsx": true + }, + "sourceType": "module" + }, + "plugins": ["flowtype", "react"], + "rules": { + "indent": ["error", 4, + { + "ObjectExpression": "first", + "CallExpression": {"arguments": "first"}, + "MemberExpression": 2, + "ignoredNodes": [ "JSXAttribute" ] + }], + "newline-per-chained-call": ["error", { "ignoreChainWithDepth": 2 }], + "lines-between-class-members": ["error", "always", { "exceptAfterSingleLine": true }], + "prefer-promise-reject-errors": ["error", { "allowEmptyReject": true }], + "react/jsx-indent": ["error", 4], + "semi": ["error", "always", { "omitLastInOneLineBlock": true }], + + "camelcase": "off", + "comma-dangle": "off", + "curly": "off", + "jsx-quotes": "off", + "key-spacing": "off", + "no-console": "off", + "quotes": "off", + "react/jsx-curly-spacing": "off", + "react/jsx-indent-props": "off", + "react/prop-types": "off", + "space-before-function-paren": "off", + "standard/no-callback-literal": "off", + + "eqeqeq": "off", + "import/no-webpack-loader-syntax": "off", + "object-property-newline": "off", + "react/jsx-no-bind": "off" + }, + "globals": { + "require": false, + "module": false + } +} diff --git a/src/cockpit/389-console/backend.html b/src/cockpit/389-console/backend.html deleted file mode 100644 index c209f96..0000000 --- a/src/cockpit/389-console/backend.html +++ /dev/null @@ -1,1007 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/cockpit/389-console/banner.html b/src/cockpit/389-console/banner.html deleted file mode 100644 index f919ed8..0000000 --- a/src/cockpit/389-console/banner.html +++ /dev/null @@ -1,17 +0,0 @@ -389 Directory Server Management - diff --git a/src/cockpit/389-console/css/ds.css b/src/cockpit/389-console/css/ds.css deleted file mode 100644 index fd1e239..0000000 --- a/src/cockpit/389-console/css/ds.css +++ /dev/null @@ -1,1425 +0,0 @@ - -.ds-logo { - margin: 5px; - background-color: white !important; -} - -.ds-logo-style { - margin: 10px; - margin-bottom: 20px; -} - -.ds-logo-hr { - padding: 0 !important; - margin-top: -20px !important; - line-height:0; -} - -.ds-title-hr { - margin: 0 !important; - padding: 0 !important; - margin-right: 10px !important; - margin-bottom: 10px !important; -} - -.ds-container { - margin: 0; - padding: 0 !important; - display: flex; -} - -.ds-inline { - display: inline-block; !important; - vertical-align: top !important; -} - -.ds-fixed { - padding: 0 !important; - padding-bottom: 10px; - width: 175px !important; - min-width: 175px !important; - margin: 2px 2px 2px 0px !important; - line-height:0; -} - -.ds-content { - padding: 0; - padding-top: 115px; - padding-bottom: 50px; - margin-top: 0; - margin-left: 25px; - margin-right: 10px; - margin-bottom: 10px; -} - - -.ds-flex { - /* background-color: #f7f7f7; */ - background-color: white !important; - flex-grow: 1; - border: 1px groove black; - border-style: groove; - margin: 6px 2px 2px 10px; - margin-left: 0px !important; - margin-right: 10px; - margin-bottom: 10px; - padding-left: 15px; - padding-right: 15px; - padding-top: 0px; - padding-bottom: 0px; - min-height: 500px; - line-height:0; - border-radius: 5px; -} - -.ds-repl-state-good { - margin: auto; - width: 30px; - height: 30px; - border-radius: 50%; - font-size: 12px; - font-weight: bold; - color: white; - line-height: 1; - text-align: center; - background-color: #4dac26; - border-color: black; - padding-top: 8px; - align-content: center !important; - vertical-align: middle !important; -} - -.ds-repl-state-bad { - margin: auto; - width: 30px; - height: 30px; - border-radius: 50%; - font-size: 12px; - font-weight: bold; - color: white; - line-height: 1; - text-align: center; - background-color: #d01c8b; - border-color: black; - padding-top: 8px; - align-content: center !important; - vertical-align: middle !important; -} - -.ds-chart-right { - margin-left: 90px; -} - -.ds-chart-left { - margin-left: 25px; - margin-bottom: 9px; -} - -.ds-chart-center { - margin-left: 100px; - margin-bottom: 15px; -} - -.ds-repl-lag-bad { - font-weight: bold; - color: #7b3294; -} - -.ds-button-border { - line-height:0; - margin: 0px; - padding-top: 0px; - padding-bottom: 10px; -} - -.ds-button { - height: 30px; - width: 160px !important; - margin-top: 5px; - float:none; - left:auto; - line-height:normal; - overflow:visible; - position:static; -} - -.ds-oc-add-del-btn { - padding: 0 !important; - margin: 10px !important; - width: 130px; - height: 26px; - text-align: center; -} - -.ds-oc-must-buttons { - padding 0 !important; - padding-left: 3px; - margin-top: 70px; - margin-bottom: 75px; - margin-left: 5px; - margin-right: 9px; -} - -.ds-oc-may-buttons { - padding 0 !important; - padding-left: 3px; - margin-top: 4px; - margin-left: 5px; - margin-right: 9px; -} - -.ds-panel { - margin: 0px 0px 0px 0px; - padding-top: 10px; - padding-left: 10px; - line-height:0; -} - -.ds-dropdown { - padding: 0px; - padding-left: 5px; - height: 35px; - width: 300px !important; - margin-top: 10px; - text-align: left; - outline: 0 !important; -} - -.ds-dropdown-server { - margin-top: 0px !important; - margin-left: 6px; - padding: 0px !important; - padding-left: 10px !important; - padding-right: 10px !important; - height: 30px; - text-align: left; -} - -.ds-passwd-dropdown { - height: 35px !important; - padding: 0px !important; - outline: 0 !important; - width: 150px !important; -} - -.ds-log-dropdown { - margin-left: 10px; - padding: 0px !important; - outline: 0 !important; - width: 65px !important; -} - -.ds-rootdn-passwd-dropdown { - margin-left: 30px; - margin-top: 5px; - padding: 10px; - outline: 0 !important; - width: 175px; - border-radius: 5px; -} - -.ds-table { - padding: 0px; - border: 1px solid #909090; - line-height:1; - margin-top: 10px !important; - margin-bottom: 10px !important; -} - -.ds-referral-table { - padding: 0px !important; - margin-top: 10px !important; - margin-bottom: 10px !important; - border: 1px solid #909090; - line-height:1; -} - -.dataTables_wrapper { - padding: 0px !important; - margin-bottom: 10px !important; -} - -td { - white-space:normal; - word-wrap: break-word !important; - max-width: 400px !important; - -} - -.ds-hr { - margin-top: 0.5em; - margin-bottom: 0.5em; - border-style: inset; - border-width: 1px; - padding: 0px !important; -} - -.ds-hr-logs { - display: block; - margin-left:0; - margin-top: 0.5em; - margin-bottom: 0.5em; - border-style: inset; - border-width: 1px; - padding: 0px !important; - width: 525px; -} - -.ds-hr-pwp { - display: block; - margin-top: 0.5em; - margin-bottom: 0.5em; - margin-left: 0 !important; - border-style: inset; - border-width: 1px; - padding: 0px !important; - width: 835px; -} - -.ds-tree { - font-size: 0.5; - background-color: #F8F8F8; - border: 1px solid #909090 ; - color: black; - line-height: 2; - width: 300px; - min-width: 300px; - min-height: 400px; - max-height: 400px; - margin: 23px 10px 2px 0px; - overflow: auto; -} - -.ds-monitor-tree { - font-size: 0.5; - background-color: #F8F8F8; - border: 1px solid #909090 ; - color: black; - line-height: 2; - width: 275px; - min-width: 275px; - min-height: 400px; - max-height: 400px; - margin: 10px; - overflow: auto; -} - -.ds-treenode { - border: 0 !important; -} - -.ds-treenode ul { - border: 0 !important; -} - -.ds-treenode li { - border: 0 !important; -} - -.ds-split { - width: 400px; -} - -.ds-modal-header { - font-size: 16px; -} - -.ds-input { - margin-top: 5px !important; - padding-right: 5px !important; - padding-left: 5px !important; -} - -.ds-pw-input { - margin-top: 5px; - padding-right: 5px; - padding-left: 5px !important; - min-width: 65px !important; - max-width: 65px !important; -} - -.ds-pw-list-input { - margin-top: 5px; - padding-right: 5px; - padding-left: 5px !important; - min-width: 150px !important; - max-width: 150px !important; -} - -.ds-ro-input { - margin-top: 5px; - padding-left: 5px; - margin-right: 5px; - background-color: #F8F8F8 !important; -} - -.ds-input-lrg { - width: 315px !important; - height: 37px !important; - margin-top: 5px; - padding-right: 10px; - height: 37px !important; -} - -.ds-input-long { - width: 500px !important; -} - -.ds-input-max { - margin-left: 10px; - margin-bottom: 20px; - width: 500px; - max-width: 600px; -} - -.ds-repl-mgr { - max-width: 600px !important; -} - -.ds-role-input { - height: 30px !important; - min-height: 30px; - margin-top: 5px; - margin-left: 7px; - border-radius: 3px; - padding-left: 5px !important; -} - -.ds-ref-input { - width: 300px !important; - padding-left: 5px; -} - -.ds-history-input { - margin-top: !important; - margin-right: 5px; - margin-left: 40px; -} - -.ds-form-input { - margin-left: 10px; -} - -.ds-divider { - width: 35px; -} - -.ds-divider-med { - width: 15px; -} - -.ds-div-right { - width: 50% !important; - margin: 2px 2px 2px 2px; -} - -.ds-div { - width: 50% !important; - margin: 2px 2px 2px 2px; -} - -.ds-button-save { - width: 100px; - margin: 2px 2px 2px 215px; -} - -.ds-changelog-button { - width: 150px; - height: 32px; - margin-top: 0px !important; - margin-left: 5px; - margin-bottom: 4px; -} - -.ds-ref-button { - margin-right: 20px; - min-width: 110px !important; - max-width: 110px !important; -} - -.ds-repl-manager { - margin-top: 5px; - padding: 5px; - resize: none; - width: 305px; - height: 100px; - white-space: pre !important; -} - -.ds-roles { - padding: 5px !important; - margin-bottom: 5px; -} - -.ds-radio { - margin: 5px !important; -} - -.ds-repl-managers-list { - width: 420px; - height: 200px; -} - -.ds-repl-managers-button { - margin-top: -15px; - margin-bottom: 10px; - margin-left: 0px; -} - -.ds-repl-manager-checkbox { - margin-top: 20px !important; - padding-top: 20px !important; - margin-left: 10px !important; - margin-right: 10px !important; -} - -.ds-label { - vertical-align: middle !important; /* Fixes any weird issues in Firefox and IE */ -} - -/* Replication styles */ -.ds-agmt-dropdown { - padding: 0px !important; - line-height: 0 !important; - overflow: visible !important; - width: auto !important; -} - -.ds-oc-dropdown { - margin-top: 5px; - color: #181818 !important; - padding: 0px !important; - line-height: 0 !important; - height: 30px; - max-height: 200px !important; - width: 315px !important; - text-align: left; - outline: 0 !important; - overflow:auto; -} - -.ds-ref-dropdown { - width: 300px !important; - text-align: left; -} - -.ds-agmt-wiz-dropdown { - width: 175px !important; - text-align: left; -} - -.ds-agmt-wiz-dropdown a { - padding: 0px !important; - padding-left: 10px !important; - line-height: 0 !important; - height: 40px; - width: 175px !important; - text-align: left; -} - -.ds-dblink-dropdown { - padding: 0px !important; - padding-right: 5px !important; - line-height: 0 !important; - width: 140px !important; - text-align: left; - outline: 0 !important; - margin-top: 5px; -} - -.ds-dblink-dropdown a { - padding: 0px !important; - padding-left: 10px !important; - line-height: 0 !important; - width: 140px !important; - text-align: left; -} - -.ds-dblink-form-input { - width: 415px !important; - margin-top: 5px; - padding-right: 10px; - height: 37px !important; -} - -.ds-agmt-dropdown-button { - width: 120px; -} - -.ds-agmt-button { - height: 40px; - width: 210px; -} - -.ds-sasl-button { - height: 35px; - width: 175px; -} - -.ds-repl-table { - background-color: white !important; - padding: 0px !important; - border: 1px solid #909090; - table-layout: fixed; - width: 100%; - clear: both; - word-wrap : break-word !important; - text-align: center; - margin-top: -10px !important; - line-height:1; -} - -.ds-sasl-table { - background-color: white !important; - padding: 0px; - border: 1px solid #909090; - table-layout: fixed; - clear: both; - word-wrap : break-word !important; - text-align: center; -} - -.ds-table { - background-color: white !important; - padding: 0px; - border: 1px solid #909090; - table-layout: fixed; - clear: both; - word-wrap : break-word !important; - text-align: center; - line-height:1; -} - -.ds-table-header th { - text-align: center !important; - background-color: white; -} - -.ds-plugin-table { - padding: 0px; - border: 1px solid #909090; - line-height:1; - table-layout: fixed; - clear: both; - word-wrap : break-word; - text-align: center; -} - -.ds-plugin-header th { - width: 100%; - text-align: center !important; -} - -.ds-plugin-panel { - background-color: #f7f7f7; - flex-grow: 1; - border: 1px groove black; - border-style: groove; - margin: 6px 2px 2px 10px; - margin-left: 10px; - margin-right: 10px; - margin-bottom: 10px; - padding-left: 15px; - padding-right: 15px; - padding-top: 0px; - padding-bottom: 0px; -} - -.ds-monitor-panel { - background-color: #f7f7f7; - flex-grow: 1; - border: 1px groove black; - border-style: groove; - margin: 6px 2px 2px 10px; - margin-left: 10px; - margin-right: 10px; - margin-bottom: 10px; - padding-left: 15px; - padding-right: 15px; - padding-top: 0px; - padding-bottom: 10px; -} - -/* - * Popup modal stuff -*/ - -/* Extra styles for the cancel button */ -.cancelbtn { - padding: 14px 20px; - background-color: #f44336; -} - -/* Float cancel and signup buttons and add an equal width */ -.cancelbtn,.savebtn { - float: left; - width: 50%; -} - -/* Add padding to container elements */ -.container { - width: 650px; - padding-left: 10px; - padding-right: 10px; - padding-bottom: 10px; -} - -.ds-modal { - width: 450px; -} - -.ds-modal-wide { - min-width: 850px; - vertical-align: middle; -} - -.modal-content { - position: absolute; - max-height: 750px; - max-width: 550px; - min-width: 400px; - overflow: auto; -} - -.ds-log-panel { - padding: 0 18px; - max-height: 0 !important; - overflow: hidden !important; - transition: max-height 0.2s ease-out !important; - margin: 2px; - display: none; -} - -.ds-suffix-panel { - padding: 0 18px; - max-height: 0 !important; - overflow: hidden !important; - transition: max-height 0.2s ease-out !important; - margin: 2px; - display: none !important; -} - -.ds-agmt-wiz-button { - height: 40px; - width: 630px; - font-weight: bold; -} - -.ds-button-right { - width: 120px !important; - margin-top: 5px; - float: right !important; - display:inline-block !important; -} - -.ds-close-button-right { - height: 40px; - width: 150px !important; - margin-top: 5px; - margin-bottom: 5px; - float: right !important; -} - -.ds-button-left { - width: 120px; - max-width: 150px; - margin-top: 5px; - float: left !important; - display:inline-block !important; -} - -.ds-panel-left { - width:50% -} -.ds-panel-right { - width:50%; -} - -.ds-fractional-panel { - background-color: white; - width: 50%; - margin: 2px 2px 2px 2px; - padding-left: 10px; -} - -.ds-fractional-panel p { - padding: 0px !important; - margin-left: 0 !important; -} - -.ds-fractional-list { - width: 230px; - min-height: 100px !important; - max-height: 100px !important; - overflow-y: scroll; -} - -.ds-fractional-btn { - width: 150px; - height: 30px; - margin: 5px 5px 5px 10px; -} - -.ds-agmt-schedule-time { - width: 75px; - padding: 10px; - margin: 5px; -} - -.ds-agmt-schedule-checkbox { - margin: 8px !important; - padding: 5px; -} - -.ds-config-checkbox { - margin-top: 10px !important; - margin-bottom: 10px !important; - margin-right: 5px !important; -} - -.ds-mgr-checkbox { - margin-left: 10px !important; - margin-top: 10px !important; - margin-bottom: 10px !important; - margin-right: 5px !important; -} - -.ds-server-checkbox { - margin-top: 15px !important; - margin-right: 12px !important; - padding: 5px; -} - -.ds-send-expiring-checkbox { - margin-top: 12px !important; - margin-right: 12px !important; - padding: 5px; -} -.ds-nowrap-td { - overflow: hidden !important; - white-space: nowrap !important; -} - -.ds-repl-bind-group-label { - width: 85px; - margin-bottom: 25px !important; -} - -.ds-config-label { - margin-top: 10px; - width: 200px !important; - margin-bottom: 10px !important; -} - -.ds-config-label-xlrg { - margin-top: 10px; - width: 180px !important; - margin-bottom: 10px !important; -} - -.ds-config-label-lrg { - margin-top: 10px; - width: 160px !important; - margin-bottom: 10px !important; -} - -.ds-config-label-med { - margin-top: 10px; - width: 100px !important; - margin-bottom: 10px !important; -} - -.ds-config-label-sm { - margin-top: 10px; - margin-right: 10px; - margin-bottom: 10px !important; -} - -.ds-config-sub-label { - margin-top: 10px; - width: 200px !important; - margin-bottom: 10px !important; - padding-left: 20px; -} - -.ds-label-lrg { - width: 200px; - margin-bottom: 10px !important; -} - -.ds-label-med { - width: 180px; - margin-bottom: 10px !important; -} - -.ds-monitor-label { - width: 155px; - margin-top: 10px; - margin-bottom: 10px !important; -} - -.ds-monitor-label-med { - width: 175px; - margin-top: 10px; - margin-bottom: 10px !important; -} - -.ds-label-sm { - width: 130px !important; - margin-bottom: 10px !important; -} - -.ds-label-xsm { - width: 100px !important; - margin-bottom: 10px !important; -} - -.ds-cleanallruv-label { - width: 110px !important; - margin-bottom: 10px !important; -} - -.ds-cache-label { - width: 210px !important; - margin-left: 20px !important; -} - -.ds-repl-config-label { - width: 210px !important; - margin-top: 20px; - margin-bottom: 20px; -} - -.ds-expire-label { - margin-top: 7px; - margin-bottom: 7px; - width: 285px !important; -} - -.ds-pw-list-label { - margin-top: 7px !important; - margin-bottom: 7px !important; - width: 200px !important; -} - -.ds-passwd-label { - width: 300px !important; -} - -.ds-minage-label { - padding: 10px; -} - -.ds-history-label { - padding: 10px; - margin-left: 50px; -} - -.ds-lockout-label { - padding: 10px; - margin-left: 20px; -} - -.ds-server-label { - padding-top: 20px; - padding-bottom: 10px; - padding-right: 60px !important; -} - -.ds-config-diskmon-label { - width: 210px !important; - padding-left: 30px; - margin-top: 10px; -} - -.ds-config-ndn-label { - padding-left: 40px; - padding-right: 10px; -} - -.ds-config-indent-sm-label { - margin-top: 10px; - margin-bottom: 10px; - width: 175px; - margin-left: 40px !important; - padding-right: 10px !important; -} - -.ds-config-indent-med-label { - margin-left: 80px !important; - padding-right: 10px !important -} - -.ds-config-indent-large-label { - margin-top: 7px; - margin-bottom: 7px; - margin-left: 120px !important; - padding-right: 10px !important; - width: 175px; -} - -.ds-expired-div { - padding-left: 30px !important; -} - -.ds-config-diskmon-checkbox { - margin: 12px !important; - padding: 5px; - margin-left: 30px !important; -} - -.ds-loglevel-list { - width: 400px; - margin-top: 10px; - margin-left: 20px; - min-height: 400px !important; -} - -.ds-accordion-spacing { - margin-bottom: 10px !important; - padding-bottom: 10px !important; -} - .ds-button-wide { - margin: 10px; - height: 40px; - width: 210px; -} - -.ds-adj-btn { - padding: 0 !important; - margin-left: 10px !important; - width: 100px !important; -} - -.ds-task-panel { - background-color: white; - border: 1px groove black; - border-style: groove; - margin: 10px; - width: 235px; - line-height:0; -} - -.ds-accordian-div { - margin-left: 20px; -} - -.ds-chaining-list { - width: 350px; - height: 100px !important; -} - -.ds-chaining-split { - width: 350px; -} - -.ds-chaining-divider { - width: 85px; -} - -.ds-chaining-form-list { - width: 355px; - height: 400px; -} - -.ds-index-form-list { - width: 363px; - height: 500px; -} - -.ds-oc-form-list { - width: 232px !important; - max-height: 350px !important; - min-height: 350px !important; -} - -.ds-oc-form-list:focus { - max-height: 350px !important; - min-height: 350px !important; -} - -.ds-may-must-list { - width: 232px !important; - height: 150px !important; - margin: 0 !important; - padding: 0 !important; -} - - -p { - line-height: 1; - white-space: normal; -} - -textarea { - margin-top: 5px; - padding-top: 5px; - vertical-align: top; - width: 315px; - height: 80px; - resize: none; - word-wrap: break-word !important; - line-height: 1; -} - -.ds-agmt-textarea { - width: 100%; -} - -.ds-logarea { - margin-top: 5px; - padding-top: 5px; - vertical-align: top; - width: 100% !important; - height: 600px !important; - max-height: 600px !important; - resize: none; - word-wrap: break-word !important; - line-height: 1; - font-family: monospace !important; - overflow-y: scroll; -} - -/* Removes dotted outline border of the text */ -select { - text-shadow: 0 0 0 #000 !important; - max-height: 200px !important; - line-height: 1; - padding: 5px; -} - -option { - color: #181818; -} - -.jstree-wholerow-hovered { - background: linear-gradient(to right, #0a676f 0%, #e5e5e5 100%) !important; - opacity: .05; -} - -.jstree-wholerow-clicked { - background-color: #0a676f !important; - background: linear-gradient(to right, #0a676f 0%, #e5e5e5 100%) !important; - opacity: .15 !important; - transition: opacity .25s ease-in-out !important; -} - -.ds-server-action { - padding: 0 !important; - margin-left: 10px; - display: inline-block; - align-content: right; -} - -.ds-action-btn { - margin-left: 10px; - margin-right: 0px; - /* border-radius: 5px !important; */ - padding: 0px 10px 0px 10px !important; - min-height: 30px !important; -} - -.ds-nav { - padding: 0 !important -} - -.ds-nav-tab a { - text-align: center; - min-width: 125px !important; -} - -.ds-float-right { - float: right; -} - -.ds-footer { - background-color: #e5e5e5 !important; - margin-left: -25px; - padding: 10px; - position: fixed; - bottom: 0; - width: 100%; - height: 50px; - border-top: 1px solid #999 !important; -} - -.ds-modal-footer { - background-color: #f5f5f5 !important; - padding: 10px; - bottom: 0; - width: 100%; - height: 50px; - border-top: 1px solid #999 !important; -} - -.ds-nav-bar { - position: fixed; - top: 0; - width: 100%; - background-color: white; - z-index:1 -} - -.ds-nav-item a { - text-align: left; -} - -.ds-config-header { - margin-bottom: 25px; -} - -.ds-sub-header { - margin-top: 25px; - margin-bottom: 10px; -} - -.ds-accordion { - margin-top: 20px; - color: #228bc0 !important; - background-color: white; - border: 0; - position: relative; - overflow: hidden; - width:700px; - text-align:left; -} - -.ds-accordion:after { - display: inline-block; - content: ""; - height: 1px; - background: #228bc0; - position: absolute; - width: 700px; - top: 50% !important; - margin-left: 10px; - text-align:left; -} - -.ds-accordion:focus { - outline: none !important; - border: 0 !important; - -moz-outline: none !important; - -webkit-box-shadow: none !important; - box-shadow: 0 !important; -} - -.ds-accordion-panel { - padding-left: 25px; - margin-top: 10px; -} - -.ds-accordion-header { - margin-bottom: 15px; - margin-top: 0px; -} - -/* wizard accordions are narrower */ -.ds-wiz-accordion { - margin-top: 20px; - color: #228bc0 !important; - background-color: white; - border: 0; - position: relative; - overflow: hidden; - width:500px; - text-align:left; -} - -.ds-wiz-accordion:after { - display: inline-block; - content: ""; - height: 1px; - background: #228bc0; - position: absolute; - width: 500px; - top: 50% !important; - margin-left: 10px; - text-align:left; -} - -.ds-wiz-accordion:focus { - outline: none !important; - border: 0 !important; - -moz-outline: none !important; - -webkit-box-shadow: none !important; - box-shadow: 0 !important; -} - -.ds-indent { - margin-left: 15px !important; - margin-right: 15px !important; -} - -.ds-left-indent { - margin-left: 15px !important; -} - -.ds-gap { - margin-bottom: 40px !important: -} - -.ds-tree-content { - margin: 33px; - margin-top: 20px; -} - -.ds-select { - height: 30px; - outline: 0 !important; - padding: 0px !important; - padding-left: 5px; - padding-right: 10px; - text-align: left; -} - -.ds-center { - text-align: center; -} - -.ds-left-margin { - margin-left: 10px !important; -} - -.ds-sm-left-margin { - margin-left: 5px !important; -} - -.ds-table-btn { - height: 30px; -} - -.ds-td { - padding-left: 10px !important; - padding-top: 8px !important; - padding-bottom: 0px ~important; - valign: middle !important; -} - -.ds-mgr-table { - max-width: 600px; - min-width: 600px; -} - -.ds-loglevel-table { - max-width: 500px; - min-width: 500px; - table-layout: fixed; - margin-top: 20px; - margin-left: 20px; -} - -.ds-table-checkbox { - width: 35px; - text-align: center; -} - -.ds-table-btn { - width: 110px; - text-align: center; -} - -.ds-page-content { - margin-top: 30px !important; -} - -.ds-checkbox-group { - margin-top: 10px !important; -} - -.ds-alert-header { - background-color: #f2dede; -} - -.ds-sec-dropdown { - width: 80px; -} - -.ds-agmt-dropdown { - width: 120px; -} - -.ds-first { - margin-top: 10px; -} - -.ds-spacing-sm { - margin-right: 10px; -} - -.ds-spacing-med { - margin-right: 20px; -} - - -.navbar-default { - margin-bottom: 0px; -} - -.ds-center { - text-align: center; -} - -.ds-modal-error { - color: red; -} - -.ds-margin-left { - margin-left: 40px !important; -} - -.ds-nested-modal { - margin-top: 100px; - margin-left: 100px; - min-width: 275px; -} - -.ds-attr-select { - min-height: 300px; - max-height: 300px; - width: 265px; - overflow: auto; -} - -.ds-center { - text-align: center; -} - -.ds-trailing-btn { - margin-left: 10px; - margin-top: -2px; -} - -.ds-suffix-cfg-div { - min-width: 500px; -} - -.ds-loading-spinner { - position: fixed; - top: 25%; - left: 50%; - transform: translate(-25%, -50%); -} - -.ds-loader { - font-size: 15px; -} - -.ds-popup { - min-width: 350px !important; -} - -.ds-disable-repl-btn { - margin-left: 15px !important; - max-height: 25px !important; -} - -.ds-repl-form { - max-width: 350px !important; -} - -.ds-input-auto { - width: 100%; - margin-right: 10px; -} - diff --git a/src/cockpit/389-console/fonts/OpenSans-Bold-webfont.woff b/src/cockpit/389-console/fonts/OpenSans-Bold-webfont.woff deleted file mode 100644 index f501db0..0000000 Binary files a/src/cockpit/389-console/fonts/OpenSans-Bold-webfont.woff and /dev/null differ diff --git a/src/cockpit/389-console/fonts/OpenSans-Bold-webfont.woff2 b/src/cockpit/389-console/fonts/OpenSans-Bold-webfont.woff2 deleted file mode 100644 index 34aac6f..0000000 Binary files a/src/cockpit/389-console/fonts/OpenSans-Bold-webfont.woff2 and /dev/null differ diff --git a/src/cockpit/389-console/fonts/OpenSans-BoldItalic-webfont.woff2 b/src/cockpit/389-console/fonts/OpenSans-BoldItalic-webfont.woff2 deleted file mode 100644 index cc8d731..0000000 Binary files a/src/cockpit/389-console/fonts/OpenSans-BoldItalic-webfont.woff2 and /dev/null differ diff --git a/src/cockpit/389-console/fonts/OpenSans-Italic-webfont.woff b/src/cockpit/389-console/fonts/OpenSans-Italic-webfont.woff deleted file mode 100644 index 9e17567..0000000 Binary files a/src/cockpit/389-console/fonts/OpenSans-Italic-webfont.woff and /dev/null differ diff --git a/src/cockpit/389-console/fonts/OpenSans-Italic-webfont.woff2 b/src/cockpit/389-console/fonts/OpenSans-Italic-webfont.woff2 deleted file mode 100644 index 9a96c63..0000000 Binary files a/src/cockpit/389-console/fonts/OpenSans-Italic-webfont.woff2 and /dev/null differ diff --git a/src/cockpit/389-console/fonts/OpenSans-Light-webfont.ttf b/src/cockpit/389-console/fonts/OpenSans-Light-webfont.ttf deleted file mode 100644 index 0d38189..0000000 Binary files a/src/cockpit/389-console/fonts/OpenSans-Light-webfont.ttf and /dev/null differ diff --git a/src/cockpit/389-console/fonts/OpenSans-Light-webfont.woff b/src/cockpit/389-console/fonts/OpenSans-Light-webfont.woff deleted file mode 100644 index fb34cf3..0000000 Binary files a/src/cockpit/389-console/fonts/OpenSans-Light-webfont.woff and /dev/null differ diff --git a/src/cockpit/389-console/fonts/OpenSans-Light-webfont.woff2 b/src/cockpit/389-console/fonts/OpenSans-Light-webfont.woff2 deleted file mode 100644 index 9a71d1c..0000000 Binary files a/src/cockpit/389-console/fonts/OpenSans-Light-webfont.woff2 and /dev/null differ diff --git a/src/cockpit/389-console/fonts/OpenSans-Regular-webfont.ttf b/src/cockpit/389-console/fonts/OpenSans-Regular-webfont.ttf deleted file mode 100644 index db43334..0000000 Binary files a/src/cockpit/389-console/fonts/OpenSans-Regular-webfont.ttf and /dev/null differ diff --git a/src/cockpit/389-console/fonts/OpenSans-Regular-webfont.woff b/src/cockpit/389-console/fonts/OpenSans-Regular-webfont.woff deleted file mode 100644 index 1251d51..0000000 Binary files a/src/cockpit/389-console/fonts/OpenSans-Regular-webfont.woff and /dev/null differ diff --git a/src/cockpit/389-console/fonts/OpenSans-Regular-webfont.woff2 b/src/cockpit/389-console/fonts/OpenSans-Regular-webfont.woff2 deleted file mode 100644 index 0964c7c..0000000 Binary files a/src/cockpit/389-console/fonts/OpenSans-Regular-webfont.woff2 and /dev/null differ diff --git a/src/cockpit/389-console/fonts/OpenSans-Semibold-webfont.ttf b/src/cockpit/389-console/fonts/OpenSans-Semibold-webfont.ttf deleted file mode 100644 index 1a7679e..0000000 Binary files a/src/cockpit/389-console/fonts/OpenSans-Semibold-webfont.ttf and /dev/null differ diff --git a/src/cockpit/389-console/fonts/OpenSans-Semibold-webfont.woff b/src/cockpit/389-console/fonts/OpenSans-Semibold-webfont.woff deleted file mode 100644 index 409c725..0000000 Binary files a/src/cockpit/389-console/fonts/OpenSans-Semibold-webfont.woff and /dev/null differ diff --git a/src/cockpit/389-console/fonts/OpenSans-Semibold-webfont.woff2 b/src/cockpit/389-console/fonts/OpenSans-Semibold-webfont.woff2 deleted file mode 100644 index d088697..0000000 Binary files a/src/cockpit/389-console/fonts/OpenSans-Semibold-webfont.woff2 and /dev/null differ diff --git a/src/cockpit/389-console/fonts/OpenSans-SemiboldItalic-webfont.woff b/src/cockpit/389-console/fonts/OpenSans-SemiboldItalic-webfont.woff deleted file mode 100644 index 5431477..0000000 Binary files a/src/cockpit/389-console/fonts/OpenSans-SemiboldItalic-webfont.woff and /dev/null differ diff --git a/src/cockpit/389-console/fonts/PatternFlyIcons-webfont.ttf b/src/cockpit/389-console/fonts/PatternFlyIcons-webfont.ttf deleted file mode 100644 index 1ed274b..0000000 Binary files a/src/cockpit/389-console/fonts/PatternFlyIcons-webfont.ttf and /dev/null differ diff --git a/src/cockpit/389-console/fonts/PatternFlyIcons-webfont.woff b/src/cockpit/389-console/fonts/PatternFlyIcons-webfont.woff deleted file mode 100644 index 8eb1d89..0000000 Binary files a/src/cockpit/389-console/fonts/PatternFlyIcons-webfont.woff and /dev/null differ diff --git a/src/cockpit/389-console/fonts/fontawesome-webfont.woff b/src/cockpit/389-console/fonts/fontawesome-webfont.woff deleted file mode 100644 index 400014a..0000000 Binary files a/src/cockpit/389-console/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/src/cockpit/389-console/fonts/fontawesome-webfont.woff2 b/src/cockpit/389-console/fonts/fontawesome-webfont.woff2 deleted file mode 100644 index 4d13fc6..0000000 Binary files a/src/cockpit/389-console/fonts/fontawesome-webfont.woff2 and /dev/null differ diff --git a/src/cockpit/389-console/fonts/glyphicons-halflings-regular.woff b/src/cockpit/389-console/fonts/glyphicons-halflings-regular.woff deleted file mode 100644 index 9e61285..0000000 Binary files a/src/cockpit/389-console/fonts/glyphicons-halflings-regular.woff and /dev/null differ diff --git a/src/cockpit/389-console/fonts/glyphicons-halflings-regular.woff2 b/src/cockpit/389-console/fonts/glyphicons-halflings-regular.woff2 deleted file mode 100644 index 64539b5..0000000 Binary files a/src/cockpit/389-console/fonts/glyphicons-halflings-regular.woff2 and /dev/null differ diff --git a/src/cockpit/389-console/images/sort_asc.png b/src/cockpit/389-console/images/sort_asc.png deleted file mode 100644 index e1ba61a..0000000 Binary files a/src/cockpit/389-console/images/sort_asc.png and /dev/null differ diff --git a/src/cockpit/389-console/images/sort_asc_disabled.png b/src/cockpit/389-console/images/sort_asc_disabled.png deleted file mode 100644 index fb11dfe..0000000 Binary files a/src/cockpit/389-console/images/sort_asc_disabled.png and /dev/null differ diff --git a/src/cockpit/389-console/images/sort_both.png b/src/cockpit/389-console/images/sort_both.png deleted file mode 100644 index af5bc7c..0000000 Binary files a/src/cockpit/389-console/images/sort_both.png and /dev/null differ diff --git a/src/cockpit/389-console/images/sort_desc.png b/src/cockpit/389-console/images/sort_desc.png deleted file mode 100644 index 0e156de..0000000 Binary files a/src/cockpit/389-console/images/sort_desc.png and /dev/null differ diff --git a/src/cockpit/389-console/images/sort_desc_disabled.png b/src/cockpit/389-console/images/sort_desc_disabled.png deleted file mode 100644 index c9fdd8a..0000000 Binary files a/src/cockpit/389-console/images/sort_desc_disabled.png and /dev/null differ diff --git a/src/cockpit/389-console/index.html b/src/cockpit/389-console/index.html deleted file mode 100644 index 38ef304..0000000 --- a/src/cockpit/389-console/index.html +++ /dev/null @@ -1,547 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/cockpit/389-console/js/backend.js b/src/cockpit/389-console/js/backend.js deleted file mode 100644 index e1a006e..0000000 --- a/src/cockpit/389-console/js/backend.js +++ /dev/null @@ -1,931 +0,0 @@ -var prev_tree_node = null; -var ref_del_html = ""; -var attr_encrypt_del_html = ""; -var index_btn_html = - ''; - -function customMenu (node) { - var dblink_items = { - "delete_link": { - "label": "Delete DB Link", - "icon": "glyphicon glyphicon-trash", - "action": function (data) { - popup_confirm("Are you sure you want to delete this Database Link?", "Confirmation", function (yes) { - if (yes) { - - // TODO Delete db link - } - }); - } - } - }; - - var suffix_items = { - 'import': { - "label": "Initialize Suffix", - "icon": "glyphicon glyphicon-circle-arrow-right", - "action": function (data) { - var suffix_id = $(node).attr('id'); - var parent_suffix = suffix_id.substring(suffix_id.indexOf('-')+1); - $("#root-suffix-import").val(parent_suffix); - $("#import-ldif-file").val(""); - $("#import-ldif-form").modal('toggle'); - } - }, - 'export': { - "label": "Export Suffix", - "icon": "glyphicon glyphicon-circle-arrow-left", - "action": function (data) { - var suffix_id = $(node).attr('id'); - var parent_suffix = suffix_id.substring(suffix_id.indexOf('-')+1); - $("#root-suffix-export").val(parent_suffix); - $("#export-ldif-file").val(""); - $("#export-ldif-form").modal('toggle'); - } - }, - 'reindex': { - "label": "Reindex Suffix", - "icon": "glyphicon glyphicon-wrench", - "action": function (data) { - popup_confirm("This will impact DB performance during the indexing. Are you sure you want to reindex all attributes?", "Confirmation", function (yes) { - if (yes) { - // TODO Reindex suffix - } - }); - } - }, - "create_db_link": { - "label": "Create Database Link", - "icon": "glyphicon glyphicon-link", - "action": function (data) { - var suffix_id = $(node).attr('id'); - var parent_suffix = suffix_id.substring(suffix_id.indexOf('-')+1); - //clear_chaining_form(); //TODO - $("#create-db-link-form").modal('toggle'); - } - }, - "create_sub_suffix": { - "label": "Create Sub-Suffix", - "icon": "glyphicon glyphicon-triangle-bottom", - "action": function (data) { - var suffix_id = $(node).attr('id'); - var parent_suffix = suffix_id.substring(suffix_id.indexOf('-')+1); - $("#parent-suffix").html('Parent Suffix:  ' + parent_suffix); - $("#add-subsuffix-dn").val(' ,' + parent_suffix); - $("#add-subsuffix-form").modal('toggle'); - } - }, - 'delete_suffix': { - "label": "Delete Suffix", - "icon": "glyphicon glyphicon-remove", - "action": function (data) { - popup_confirm("Are you sure you want to delete suffix?", "Confirmation", function (yes) { - if (yes) { - // TODO - } - }); - } - } - }; - - if ( $(node).attr('id').startsWith('suffix') ){ - return suffix_items; - } else { - // chaining - return dblink_items; - } -}; - -function get_encoded_ref () { - var ref_encoded = $("#ref-protocol").val() + $("#ref-hostname").val(); - var ref_port = $("#ref-port").val(); - var ref_suffix = $("#ref-suffix").val(); - var ref_attrs = $("#ref-attrs").val(); - var ref_filter = $("#ref-filter").val(); - var ref_scope = $("#ref-scope").val(); - - $("#preview-ref-btn").blur(); - - if (ref_port != ""){ - ref_encoded += ":" + ref_port; - } - - if (ref_suffix == "" && (ref_attrs != "" || ref_filter != "" || ref_scope != "")) { - popup_msg("Attention!", "Missing suffix - you can not set the attributes, scope, or filter without a suffix."); - return; - } - if (ref_suffix != "" || ref_attrs != "" || ref_filter != "" || ref_scope != "") { - ref_encoded += "/" + encodeURIComponent(ref_suffix); - if ( ref_attrs != "" ) { - ref_encoded += "?" + encodeURIComponent(ref_attrs); - } else if ( ref_filter != "" || ref_scope != "" ) { - ref_encoded += "?"; - } - if ( ref_scope != "" ) { - ref_encoded += "?" + encodeURIComponent(ref_scope); - } else if ( ref_filter != "" ) { - ref_encoded += "?"; - } - if ( ref_filter != "") { - ref_encoded += "?" + encodeURIComponent(ref_filter); - } - } - return ref_encoded; -} - -function load_jstree() { - $('#db-tree').jstree({ - "plugins": [ "contextmenu", "wholerow", "sort" ], - "contextmenu": { - "items" : customMenu - }, - "core": { - "check_callback": true - } - }); - - $('#db-tree').jstree('select_node', 'ul > li:first'); - - - $('#db-tree').on("changed.jstree", function (e, data) { - var node_type = data.selected[0]; - var suffix = data.instance.get_node(data.selected[0]).text.replace(/(\r\n|\n|\r)/gm,""); - - if (node_type.startsWith("dblink")) { - var parent_suffix = node_type.substring(node_type.indexOf('-')+1); - $(".all-pages").hide(); - $("#database-content").show(); - $("#db-page").show(); - $("#chaining-header").html("Database Chaining Configuration (" + parent_suffix + ")"); - $("#chaining-page").show(); - } else { - // suffix - $(".all-pages").hide(); - $("#database-content").show(); - $("#db-page").show(); - $("#suffix-header").html("Suffix Configuration (" + suffix + ")"); - $("#suffix-page").show(); - } - }); -}; - -function clear_ref_form () { - $("#ref-scope").prop('selectedIndex',0); - $("#ref-protocol").prop('selectedIndex',0); - $("#ref-suffix").val(""); - $("#ref-filter").val(""); - $("#ref-hostname").val(""); - $("#ref-port").val(""); - $("#ref-attrs").val(""); - $("#ref-preview-field").val(""); -} - -function clear_index_form () { - $("#index-list-select").prop('selectedIndex',0); - $("#add-index-type-eq").prop('checked', false); - $("#add-index-type-pres").prop('checked', false); - $("#add-index-type-sub").prop('checked', false); - $("#add-index-type-approx").prop('checked', false); - $("#add-index-matchingrules").val(""); -} - -function clear_attr_encrypt_form() { - $("#attr-encrypt-list").prop('selectedIndex',0); - $("#nsencryptionalgorithm").prop('selectedIndex',0); -} - -$(document).ready( function() { - $("#database-content").load("backend.html", function () { - load_jstree(); - - $(".ds-suffix-panel").toggle("active"); - $(".ds-suffix-panel").css('display','none'); - - $("#create-ref-btn").on("click", function () { - clear_ref_form(); - }); - - $("#db-chaining-btn").on("click", function() { - $(".all-pages").hide(); - $("#database-content").show(); - $("#db-chaining-settings-page").show(); - }); - $("#db-global-btn").on("click", function() { - $(".all-pages").hide(); - $("#database-content").show(); - $("#db-global-page").show(); - }); - $("#db-suffix-btn").on("click", function() { - $(".all-pages").hide(); - $("#database-content").show(); - $("#db-page").show(); - $("#suffix-page").show(); - }); - - $("#chaining-adv-accordion").on("click", function() { - this.classList.toggle("active"); - var panel = this.nextElementSibling; - if (panel.style.display === "block") { - var show = "► Show Advanced Database Link Settings "; - $(this).html(show); - panel.style.display = "none"; - $(this).blur(); - } else { - var hide = "▼ Hide Advanced Database Link Settings"; - $(this).html(hide); - panel.style.display = "block"; - $(this).blur(); - } - }); - - - $("#db-system-index-accordion").on("click", function() { - this.classList.toggle("active"); - var panel = this.nextElementSibling; - if (panel.style.display === "block") { - var show = "► Show System Indexes "; - $(this).html(show); - panel.style.display = "none"; - $(this).blur(); - } else { - var hide = "▼ Hide System Indexes "; - $(this).html(hide); - panel.style.display = "block"; - $(this).blur(); - } - }); - - $("#db-index-accordion").on("click", function() { - this.classList.toggle("active"); - var panel = this.nextElementSibling; - if (panel.style.display === "block") { - var show = "► Show Database Indexes "; - $(this).html(show); - panel.style.display = "none"; - $(this).blur(); - } else { - var hide = "▼ Hide Database Indexes "; - $(this).html(hide); - panel.style.display = "block"; - $(this).blur(); - } - }); - - $("#suffix-attrencrypt-accordion").on("click", function() { - this.classList.toggle("active"); - var panel = this.nextElementSibling; - if (panel.style.display === "block") { - var show = "► Show Encrypted Attributes "; - $(this).html(show); - panel.style.display = "none"; - $(this).blur(); - } else { - var hide = "▼ Hide Encrypted Attributes "; - $(this).html(hide); - panel.style.display = "block"; - $(this).blur(); - } - }); - - - /* - We need logic to see if autocaching (import and db) is being used, and disable fields, - and set radio buttons, et - */ - - var ref_table = $('#referral-table').DataTable( { - "paging": false, - "searching": false, - "bInfo" : false, - "bAutoWidth": false, - "dom": '<"pull-left"f><"pull-right"l>tip', - "language": { - "emptyTable": "No Referrals" - }, - "columnDefs": [ - { - "targets": 1, - "orderable": false, - }, - { - "targets": 1, - "className": "ds-center" - } - ] - }); - - - $('#system-index-table').DataTable( { - "paging": true, - "bAutoWidth": false, - "dom": '<"pull-left"f><"pull-right"l>tip', - "lengthMenu": [ 10, 25, 50, 100], - "language": { - "search": "Search", - "emptyTable": "No System Indexes" - }, - "columns": [ - { "width": "10%" }, - { "width": "20px" }, - { "width": "20px" }, - { "width": "20px" }, - { "width": "20px" }, - { "width": "20%" } - ], - }); - var index_table = $('#index-table').DataTable( { - "paging": true, - "bAutoWidth": false, - "dom": '<"pull-left"f><"pull-right"l>tip', - "lengthMenu": [ 10, 25, 50, 100], - "language": { - "search": "Search", - "emptyTable": "No Indexes" - }, - "columns": [ - { "width": "10%" }, - { "width": "15px" }, - { "width": "15px" }, - { "width": "15px" }, - { "width": "15px" }, - { "width": "20%" }, - { "width": "76px" } - ], - "columnDefs": [ { - "targets": 6, - "orderable": false - } ] - }); - - - - - var attr_encrypt_table = $('#attr-encrypt-table').DataTable( { - "paging": true, - "bAutoWidth": false, - "searching": true, - "dom": '<"pull-left"f><"pull-right"l>tip', - "lengthMenu": [ 10, 25, 50, 100], - "language": { - "search": "Search", - "emptyTable": "No Encrypted Attributes" - }, - "columnDefs": [ { - "targets": 2, - "orderable": false - } ] - }); - - // Accordion opening/closings - $(".ds-accordion-panel").css('display','none'); - - var suffix_acc = document.getElementsByClassName("suffix-accordion"); - for (var i = 0; i < suffix_acc.length; i++) { - suffix_acc[i].onclick = function() { - this.classList.toggle("active"); - var panel = this.nextElementSibling; - if (panel.style.display === "block") { - panel.style.display = "none"; - } else { - panel.style.display = "block"; - } - } - } - - $("#db-accordion").on("click", function() { - this.classList.toggle("active"); - var panel = this.nextElementSibling; - if (panel.style.display === "block") { - var show = "► Show Advanced Settings"; - $(this).html(show); - panel.style.display = "none"; - $(this).blur(); - } else { - var hide = "▼ Hide Advanced Settings "; - $(this).html(hide); - panel.style.display = "block"; - $(this).blur(); - } - }); - - var db_acc = document.getElementsByClassName("db-accordion"); - for (var i = 0; i < db_acc.length; i++) { - db_acc[i].onclick = function() { - this.classList.toggle("active"); - var panel = this.nextElementSibling; - if (panel.style.display === "block") { - panel.style.display = "none"; - } else { - panel.style.display = "block"; - } - } - } - - var cache_acc = document.getElementsByClassName("cache-accordion"); - for (var i = 0; i < cache_acc.length; i++) { - cache_acc[i].onclick = function() { - this.classList.toggle("active"); - var panel = this.nextElementSibling; - if (panel.style.display === "block") { - panel.style.display = "none"; - } else { - panel.style.display = "block"; - } - } - } - - - $(".index-type").attr('readonly', true); - - if ( $("#manual-cache").is(":checked") ){ - $("#auto-cache-form").hide(); - $("#manual-cache-form").show(); - $("#nsslapd-dncachememsize").prop('disabled', false); - $("#nsslapd-dncachememsize").val(''); - $("#nsslapd-cachememsize").prop('disabled', false); - $("#nsslapd-cachememsize").val(''); - $("#nsslapd-cachesize").prop('disabled', false); - $("#nsslapd-cachesize").val(''); - } else { - $("#manual-cache-form").hide(); - $("#auto-cache-form").show(); - $("#nsslapd-dncachememsize").prop('disabled', true); - $("#nsslapd-dncachememsize").val('AUTOTUNED'); - $("#nsslapd-cachememsize").prop('disabled', true); - $("#nsslapd-cachememsize").val('AUTOTUNED'); - $("#nsslapd-cachesize").prop('disabled', true); - $("#nsslapd-cachesize").val('AUTOTUNED'); - } - - if ( $("#manual-import-cache").is(":checked") ){ - $("#auto-import-cache-form").hide(); - $("#manual-import-cache-form").show(); - } else { - $("#manual-import-cache-form").hide(); - $("#auto-import-cache-form").show(); - } - - $(".cache-role").on("change", function() { - var cache_role = $("input[name=cache-role]:checked").val(); - if (cache_role == "manual-cache") { - $("#auto-cache-form").hide(); - $("#manual-cache-form").show(); - } else { - // auto cache - $("#manual-cache-form").hide(); - $("#auto-cache-form").show(); - } - }); - - $(document).on('click', '.del-ref-btn', function(e) { - e.preventDefault(); - var data = ref_table.row( $(this).parents('tr') ).data(); - var del_ref_name = data[0]; - var ref_row = $(this); // Store element for callback - popup_confirm("Are you sure you want to delete referral: " + del_ref_name + "", "Confirmation", function (yes) { - if (yes) { - // TODO Delete mapping from DS - - // Update html table - ref_table.row( ref_row.parents('tr') ).remove().draw( false ); - } - }); - }); - - $("#backend-config-save-btn").on("click", function () { - var role = $("input[name=cache-role]:checked").val(); - if (role == "manual-cache") { - // TODO - need to get cache values and fields (overwrite AUTOTUNED) - $("#nsslapd-dncachememsize").prop('disabled', false); - $("#nsslapd-dncachememsize").val('') - $("#nsslapd-cachememsize").prop('disabled', false); - $("#nsslapd-cachememsize").val(''); - $("#nsslapd-cachesize").prop('disabled', false); - $("#nsslapd-cachesize").val(''); - } else { - // auto cache - $("#nsslapd-dncachememsize").prop('disabled', true); - $("#nsslapd-dncachememsize").val('AUTOTUNED'); - $("#nsslapd-cachememsize").prop('disabled', true); - $("#nsslapd-cachememsize").val('AUTOTUNED'); - $("#nsslapd-cachesize").prop('disabled', true); - $("#nsslapd-cachesize").val('AUTOTUNED'); - } - }); - - $(".import-cache-role").on("change", function() { - var role = $("input[name=import-cache-role]:checked").val(); - if (role == "manual-import-cache") { - $("#auto-import-cache-form").hide(); - $("#manual-import-cache-form").show(); - } else { - // auto cache - $("#manual-import-cache-form").hide(); - $("#auto-import-cache-form").show(); - } - }); - - // Based on the db-link connection type change the agmt-auth options - $("#dblink-conn").change(function() { - var ldap_opts = {"Simple": "Simple", - "SASL/DIGEST-MD5": "SASL/DIGEST-MD5", - "SASL/GSSAPI": "SASL/GSSAPI"}; - var ldaps_opts = {"Simple": "Simple", - "SSL Client Authentication": "SSL Client Authentication", - "SASL/DIGEST-MD5": "SASL/DIGEST-MD5"}; - var $auth = $("#nsbindmechanism"); - $auth.empty(); - var conn = $('#dblink-conn').val(); - if (conn == "LDAP"){ - $.each(ldap_opts, function(key, value) { - $auth.append($("").attr("value", value).text(key)); - }); - } else { - // TLS options - $.each(ldaps_opts, function(key, value) { - $auth.append($("").attr("value", value).text(key)); - }); - } - $("#nsmultiplexorbinddn").prop('disabled', false); - $("#nsmultiplexorcredentials").prop('disabled', false); - $("#nsmultiplexorcredentials-confirm").prop('disabled', false); - }); - - // Check for auth changes and disable/enable bind DN & password for db-links - $("#nsbindmechanism").change(function() { - var authtype = $('#nsbindmechanism').val(); - if (authtype == "SSL Client Authentication") { - $("#nsmultiplexorbinddn").prop('disabled', true); - $("#nsmultiplexorcredentials").prop('disabled', true); - $("#nsmultiplexorcredentials-confirm").prop('disabled', true); - } else { - $("#nsmultiplexorbinddn").prop('disabled', false); - $("#nsmultiplexorcredentials").prop('disabled', false); - $("#nsmultiplexorcredentials-confirm").prop('disabled', false); - } - }); - - // - // Modal Forms - // - - // Chaining OIDS - $("#chaining-oid-button").on("click", function() { - $(this).blur(); - }); - $("#chaining-oid-save").on("click", function() { - // Update oids - var chaining_oids = $("#avail-chaining-oid-list").val(); - for (var i = 0; chaining_oids && i < chaining_oids.length; i++) { - $('#chaining-oid-list').append($(''); - $("#select-server").prop('selectedIndex',0); - - server_id = ""; - server_inst = ""; - - $("#server-list-menu").attr('disabled', true); - $("#ds-navigation").hide(); - $(".all-pages").hide(); - $("#no-instances").show(); -} - -function check_for_389 () { - var cmd = ["rpm", "-q", "389-ds-base"]; - - cockpit.spawn(cmd, { superuser: true }).fail(function(data) { - $("#server-list-menu").attr('disabled', true); - $("#ds-navigation").hide(); - $(".all-pages").hide(); - $("#no-package").show(); - }); -} - -function check_inst_alive (connect_err) { - // Check if this instance is started, if not hide configuration pages - if (connect_err === undefined) { - connect_err = 0; - } - cmd = ['status-dirsrv', server_inst]; - cockpit.spawn(cmd, { superuser: true }).done(function () { - if (connect_err) { - $("#ds-navigation").hide(); - $(".all-pages").hide(); - $("#no-connect").show(); - } else { - // if nav page was hidden reset everything - if ($("#ds-navigation").is(":hidden") ){ - $(".all-pages").hide(); - $("#ds-navigation").show(); - $("#server-content").show(); - $("#server-config").show(); - } - $("#not-running").hide(); - $("#no-connect").hide(); - } - }).fail(function(data) { - $("#loading-page").hide(); - $("#ds-navigation").hide(); - $(".all-pages").hide(); - $("#not-running").show(); - }); -} - -function get_insts() { - // Load initial forms - $("#server-list-menu").attr('disabled', false); - $("#ds-navigation").show(); - $(".all-pages").hide(); - $("#no-instances").hide(); - - var insts = []; - var cmd = ["/bin/sh", "-c", "/usr/bin/ls -d " + DS_HOME + "slapd-*"]; - cockpit.spawn(cmd, { superuser: true }).done(function(data) { - // Parse the output, and skip removed instances and empty lines - var lines = data.split('\n'); - var i = 0; - for (i = 0; i < lines.length; i++) { - if (lines[i].endsWith(".removed") == false && lines[i] != "") { - var serverid = lines[i].replace(DS_HOME, ""); - insts.push(serverid); - } - } - - if (server_id != "None") { - $("#ds-banner").html("Managing Instance "); - } - - // Populate the server instance drop down - $("#select-server").empty(); - for (i = 0; i < insts.length; i++) { - $("#select-server").append(''); - } - $("#select-server").prop('selectedIndex',0); - - if (insts[0] === undefined) { - set_no_insts(); - $("#loading-page").hide(); - $("#everything").show(); - } else { - // We have at least one instance, make sure we "open" the UI - server_id = insts[0]; - server_inst = insts[0].replace("slapd-", ""); - check_inst_alive(); - load_config(); - } - }).fail(function(error){ - set_no_insts(); - $("#loading-page").hide(); - $("#everything").show(); - }); -} - -function report_err( input, msg) { - $(".ds-modal-error").html('Error: ' + msg); - input.css("border-color", "red"); - $(".ds-modal-error").show(); -} - - -function popup_err(title, msg) { - // Display errors from the cli (we have to use pre tags) - bootpopup({ - title: title, - content: [ - '
' + msg + '
' - ] - }); - check_inst_alive(0); -} - -function popup_msg(title, msg) { - bootpopup({ - title: title, - content: [ - '

' + msg + '

' - ] - }); -} - -function popup_confirm(msg, title, callback) { - if(typeof callback !== "function") { - callback = function() {}; - } - var answer = false; - return bootpopup({ - title: title, - content: [ - msg - ], - showclose: false, - buttons: ["no", "yes"], - yes: function() { answer = true; }, - dismiss: function() { callback(answer); }, - }); -} - -function popup_success(msg) { - $('#success-msg').html(msg); - $('#success-form').modal('show'); - setTimeout(function() {$('#success-form').modal('hide');}, 2000); -} - -// This is called when any Save button is clicked on the main page. We call -// all the save functions for all the pages here. This is not used for modal forms -function save_all () { - save_config(); // Server Config Page - // - // TODO: - // save_chaining(); - // save_chaining_suffix(); - // save_global_backend(); - // save_suffix(); - // save_security(); -} - -function load_config (){ - // Load the configuration for all the pages. - var dropdowns = ['local-pwp-suffix', 'select_repl_suffix', 'select-repl-cfg-suffix', - 'select-repl-agmt-suffix', 'select-repl-winsync-suffix', - 'cleanallruv-suffix', 'monitor-repl-backend-list']; - - // Show the spinner, and reset the pages - $("#loading-msg").html("Loading Directory Server configuration for " + server_id + "..."); - $("#everything").hide(); - $(".all-pages").hide(); - $("#loading-page").show(); - config_loaded = 0; - - /* - * Start with the dropdowns, if this fails we stop here, otherwise we assume - * we are up and running and we can load the other config/ - */ - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','backend', 'list', '--suffix']; - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - // Update dropdowns - for (var idx in dropdowns) { - $("#" + dropdowns[idx]).empty(); - } - var obj = JSON.parse(data); - for (var idx in obj['items']) { - for (var list in dropdowns){ - $("#" + dropdowns[list]).append(''); - } - } - - // Server page - get_and_set_config(); - get_and_set_sasl(); - get_and_set_localpwp(); - - // Schema page - get_and_set_schema_tables(); - - // Replication page - get_and_set_repl_config(); - get_and_set_repl_agmts(); - get_and_set_repl_winsync_agmts(); - get_and_set_cleanallruv(); - - // Security page - // Database page - // Plugin page - // Monitoring page - - // Initialize the tabs - $(".ds-tab-list").css( 'color', '#777'); - $("#server-tab").css( 'color', '#228bc0'); - - // Set an interval event to wait for all the pages to load, then show the content - var loading_config = setInterval(function() { - if (config_loaded == 1) { - $("#loading-page").hide(); - $("#everything").show(); - $("#server-content").show(); - $("#server-config").show(); - clearInterval(loading_config); - console.log("Completed configuration initialization."); - } - }, 300); - - }).fail(function(data) { - popup_err("Failed To Contact Server",data.message); - $("#everything").show(); - check_inst_alive(1); - }); -} - -$(window.document).ready(function() { - if(navigator.userAgent.toLowerCase().indexOf('firefoxf') > -1) { - $("select@@@").focus( function() { - this.style.setProperty( 'outline', 'none', 'important' ); - this.style.setProperty( 'color', 'rgba(0,0,0,0)', 'important' ); - this.style.setProperty( 'text-shadow', '0 0 0 #000', 'important' ); - }); - } -}); - - diff --git a/src/cockpit/389-console/js/monitor.js b/src/cockpit/389-console/js/monitor.js deleted file mode 100644 index 1774d15..0000000 --- a/src/cockpit/389-console/js/monitor.js +++ /dev/null @@ -1,398 +0,0 @@ - -var accesslog_cont_refresh; -var auditlog_cont_refresh; -var auditfaillog_cont_refresh; -var errorslog_cont_refresh; - -var sev_emerg = " - EMERG - "; -var sev_crit = " - CRIT - "; -var sev_alert = " - ALERT - "; -var sev_err = " - ERR - "; -var sev_warn = " - WARN - "; -var sev_notice = " - NOTICE - "; -var sev_info = " - INFO - "; -var sev_debug = " - DEBUG - "; -var sev_levels = {"Emergency": sev_emerg, - "Critical": sev_crit, - "Alert": sev_alert, - "Error": sev_err, - "Warning": sev_warn, - "Notice": sev_notice, - "Info": sev_info, - "Debug": sev_debug - }; -var sev_all_errs = [sev_emerg, sev_crit, sev_alert, sev_err]; -var sev_all_info = [sev_warn, sev_notice, sev_info, sev_debug]; - - -function gen_ratio_chart(ratio, chart ) { - var c3ChartDefaults = patternfly.c3ChartDefaults(); - var donutConfig = c3ChartDefaults.getDefaultDonutConfig(ratio + "%"); - var miss = 100 - ratio; - var donut_color = patternfly.pfPaletteColors.lightGreen; - if (ratio < 90) { - donut_color = patternfly.pfPaletteColors.red; - } - donutConfig.bindto = chart; - donutConfig.data = { - type: "donut", - columns: [ - ["Hit Ratio", ratio], - ["Miss", miss], - ], - colors: { - 'Hit Ratio': donut_color, - 'Miss': "#D8D8D8" - }, - order: null - }; - donutConfig.size = { - width: 120, - height: 80 - }; - - c3.generate(donutConfig); -}; - -function gen_util_chart(used, maxsize, hitratio, chart ) { - var c3ChartDefaults = patternfly.c3ChartDefaults(); - var ratio = Math.round((used / maxsize) * 100); - var donutConfig = c3ChartDefaults.getDefaultDonutConfig(ratio + "%"); - var avail = maxsize - used; - donutConfig.bindto = chart; - var donut_color = patternfly.pfPaletteColors.lightGreen; - if (hitratio < 90 && ratio > 90) { - donut_color = patternfly.pfPaletteColors.red; - } - - donutConfig.data = { - type: "donut", - columns: [ - ["Used", used], - ["Available", avail], - ], - colors: { - 'Used': donut_color, - 'Available': "#D8D8D8" - }, - order: null - }; - donutConfig.size = { - width: 120, - height: 80 - }; - c3.generate(donutConfig); -}; - -/* - * Refresh logs - */ -function refresh_access_log () { - var access_log = "/var/log/dirsrv/" + server_id + "/access"; // TODO - get actual log location from config - var lines = $("#accesslog-lines").val(); - var logging = cockpit.spawn(["tail", "-" + lines, access_log], - { "superuser": "try" }).done(function(data) { - $("#accesslog-area").text(data); - }); -} - -function refresh_audit_log () { - var audit_log = "/var/log/dirsrv/" + server_id + "/audit"; // TODO - get actual log location from config - var lines = $("#auditlog-lines").val(); - var logging = cockpit.spawn(["tail", "-" + lines, audit_log], - { "superuser": "try" }).done(function(data) { - $("#auditlog-area").text(data); - }); -} - -function refresh_auditfail_log () { - var auditfail_log = "/var/log/dirsrv/" + server_id + "/auditfail"; // TODO - get actual log location from config - var lines = $("#auditfaillog-lines").val(); - var logging = cockpit.spawn(["tail", "-" + lines, auditfail_log], - { "superuser": "try" }).done(function(data) { - $("#auditfaillog-area").text(data); - }); -} - -function refresh_errors_log () { - var errors_log = "/var/log/dirsrv/" + server_id + "/errors"; // TODO - get actual log location from config - var lines = $("#errorslog-lines").val(); - var sev_level = $("#errorslog-sev-level").val(); - var logging = cockpit.spawn(["tail", "-" + lines, errors_log], - { "superuser": "try" }).done(function(data) { - if (sev_level != "Everything"){ - // Filter Data - var lines = data.split('\n'); - var new_data = ""; - for (var i = 0; i < lines.length; i++){ - var line = ""; - if (sev_level == "Error Messages"){ - for (var lev = 0; lev < sev_all_errs.length; lev++) { - if (lines[i].indexOf(sev_all_errs[lev]) != -1){ - line = lines[i] + "\n"; - } - } - } else if (sev_level == "Info Messages"){ - for (var lev = 0; lev < sev_all_info.length; lev++) { - if (lines[i].indexOf(sev_all_info[lev]) != -1){ - line = lines[i] + "\n"; - } - } - } else if (lines[i].indexOf(sev_levels[sev_level]) != -1){ - line = lines[i] + "\n"; - } - // Add the filtered line to new data - new_data += line; - } - data = new_data; - } - $("#errorslog-area").text(data); - }); -} - - -$(document).ready( function() { - $("#monitor-content").load("monitor.html", function () { - $('#monitor-db-tree').jstree({ - "plugins": [ "contextmenu", "wholerow" ], - }); - - $("#monitor-server-btn").on("click", function() { - $(".all-pages").hide(); - $("#monitor-content").show(); - $("#monitor-server-page").show(); - }); - - $("#monitor-db-btn").on("click", function() { - $(".all-pages").hide(); - $("#monitor-content").show(); - - // TODO - NDN cache prior to 1.4.0 is duplicated under each suffix/backend monitor - - // so we need to bring it forward to the global database stats here - var db_hitratio = '99'; - var ndn_hitratio = '83'; - var ndn_maxsize = '25165824'; - var ndn_cursize = '19891200'; - gen_ratio_chart(db_hitratio, '#monitor-db-cache-hitratio-chart'); - gen_ratio_chart(ndn_hitratio, '#monitor-ndn-cache-hitratio-chart'); - gen_util_chart(ndn_cursize, ndn_maxsize, ndn_hitratio, '#monitor-ndn-cache-util-chart'); - - $("#monitor-db-page").show(); - }); - - - $("#monitor-snmp-btn").on("click", function() { - $(".all-pages").hide(); - $("#monitor-content").show(); - $("#monitor-snmp-page").show(); - }); - - $("#monitor-repl-btn").on("click", function() { - $(".all-pages").hide(); - $("#monitor-content").show(); - $("#monitor-repl-page").show(); - }); - - $("#monitor-log-access-btn").on("click", function() { - $(".all-pages").hide(); - $("#monitor-content").show(); - refresh_access_log(); - $("#monitor-log-access-page").show(); - }); - $("#monitor-log-audit-btn").on("click", function() { - $(".all-pages").hide(); - $("#monitor-content").show(); - refresh_audit_log(); - $("#monitor-log-audit-page").show(); - }); - $("#monitor-log-auditfail-btn").on("click", function() { - $(".all-pages").hide(); - $("#monitor-content").show(); - refresh_auditfail_log() - $("#monitor-log-auditfail-page").show(); - }); - $("#monitor-log-errors-btn").on("click", function() { - $(".all-pages").hide(); - $("#monitor-content").show(); - refresh_errors_log(); - $("#monitor-log-errors-page").show(); - }); - - $("#accesslog-refresh-btn").on('click', function () { - refresh_access_log(); - }); - $("#auditlog-refresh-btn").on('click', function () { - refresh_audit_log(); - }); - $("#auditfaillog-refresh-btn").on('click', function () { - refresh_auditfail_log(); - }); - $("#errorslog-refresh-btn").on('click', function () { - refresh_errors_log(); - }); - - $('#monitor-db-tree').on("changed.jstree", function (e, data) { - var tree_node = data.selected; - if (tree_node == "monitor-db-main") { - - // TODO - NDN cache prior to 1.4.0 is duplicated under each suffix/backend monitor - - // so we need to bring it forward to the global database stats here - var db_hitratio = '99'; - var ndn_hitratio = '83'; - var ndn_maxsize = '25165824'; - var ndn_cursize = '19891200'; - - gen_ratio_chart(db_hitratio, '#monitor-db-cache-hitratio-chart'); - gen_ratio_chart(ndn_hitratio, '#monitor-ndn-cache-hitratio-chart'); - gen_util_chart(ndn_cursize, ndn_maxsize, ndn_hitratio, '#monitor-ndn-cache-util-chart'); - $("#monitor-suffix-page").hide(); - $("#db-content").show(); - } else if (tree_node[0].startsWith("monitor-suffix-")) { - /* - * Gather and set the Suffix info - */ - var monitor_suffix = tree_node[0].replace("monitor-suffix-", ""); - $("#monitor-suffix-header").html("" + monitor_suffix + ""); - - // TODO - get the monitor info. For now uses DEMO values for the charts - var entry_hitratio = '96'; - var entry_maxsize = '512000'; - var entry_cursize = '395000'; - var dn_hitratio = '89'; - var dn_maxsize = '51200'; - var dn_cursize = '51200'; - - // Generate the donut charts - gen_ratio_chart(entry_hitratio, '#monitor-entry-cache-hitratio-chart'); - gen_util_chart(entry_cursize, entry_maxsize, entry_hitratio, '#monitor-entry-cache-util-chart'); - gen_ratio_chart(dn_hitratio, '#monitor-dn-cache-hitratio-chart'); - gen_util_chart(dn_cursize, dn_maxsize, dn_hitratio, '#monitor-dn-cache-util-chart'); - $("#db-content").hide(); - $("#monitor-suffix-page").show(); - } - }); - - var monitor_conn_table = $('#monitor-conn-table').DataTable( { - "paging": true, - "bAutoWidth": false, - "searching": false, - "dom": '<"pull-left"f><"pull-right"l>tip', - "lengthChange": false, - "lengthMenu": [ 10, 25, 50, 100], - "language": { - "emptyTable": "No active connections", - "search": "Search Connections" - } - }); - var monitor_index_table = $('#monitor-index-table').DataTable( { - "paging": true, - "bAutoWidth": false, - "dom": '<"pull-left"f><"pull-right"l>tip', - "lengthMenu": [ 10, 25, 50, 100], - "language": { - "emptyTable": "No Attribute Indexes", - "search": "Search Indexes" - } - }); - - $.fn.dataTable.moment( 'HH:mm:ss' ); - var monitor_repl_table = $('#monitor-repl-table').DataTable( { - "paging": true, - "bAutoWidth": false, - "dom": '<"pull-left"f><"pull-right"l>tip', - "lengthMenu": [ 10, 25, 50, 100], - "language": { - "emptyTable": "No Replication Agreements", - "search": "Search" - } - }); - - var monitor_winsync_table = $('#monitor-winsync-table').DataTable( { - "paging": true, - "bAutoWidth": false, - "dom": '<"pull-left"f><"pull-right"l>tip', - "lengthMenu": [ 10, 25, 50, 100], - "language": { - "emptyTable": "No Winsync Agreements", - "search": "Search" - } - }); - - // The continuous log refresh intervals - $("#accesslog-cont-refresh").change(function() { - if(this.checked) { - accesslog_cont_refresh = setInterval(refresh_access_log, 1000); - } else { - clearInterval(accesslog_cont_refresh); - } - }); - - $("#auditlog-cont-refresh").change(function() { - if(this.checked) { - auditlog_cont_refresh = setInterval(refresh_audit_log, 1000); - } else { - clearInterval(auditlog_cont_refresh); - } - }); - - $("#auditfaillog-cont-refresh").change(function() { - if(this.checked) { - auditfaillog_cont_refresh = setInterval(refresh_auditfail_log, 1000); - } else { - clearInterval(auditfaillog_cont_refresh); - } - }); - - $("#errorslog-cont-refresh").change(function() { - if(this.checked) { - errorslog_cont_refresh = setInterval(refresh_errors_log, 1000); - } else { - clearInterval(errorslog_cont_refresh); - } - }); - - // Refresh page after changing severity level - $("#errorslog-sev-level").on("change", function() { - refresh_errors_log(); - }); - - $(document).on('click', '.repl-detail-btn', function(e) { - e.preventDefault(); - var data = monitor_repl_table.row( $(this).parents('tr') ).data(); - var agmt_name = data[0]; - var agmt_suffix = data[2]; - var agmt_enabled = "off"; // TODO Need to determine this from DS data - var agmt_status = ""; - if (agmt_enabled == "off") { - agmt_status = " (Agreement Disabled)"; - } - // clear_agmt_form(); - - $("#monitor-agmt-header").html("Replication Agreement Details:   " + agmt_name + " " + agmt_status); - - // TODO - get agreement details and populate form - $("#monitor-agmt-form").css('display', 'block'); - }); - - - $(document).on('click', '.repl-winsync-detail-btn', function(e) { - e.preventDefault(); - var data = monitor_repl_table.row( $(this).parents('tr') ).data(); - var agmt_name = data[0]; - var agmt_suffix = data[2]; - var agmt_enabled = "on"; // TODO Need to determine this from DS data - var agmt_status = ""; - if (agmt_enabled == "off") { - agmt_status = " (Agreement Disabled)"; - } - // clear_agmt_form(); - - $("#repl-winsync-agmt-header").html("Winsync Agreement Details:   " + agmt_name + " " + agmt_status); - // TODO - get agreement details and populate form - $("#monitor-winsync-agmt-form").css('display', 'block'); - }); - - // Page is loaded, mark it as so... - monitor_page_loaded = 1; - }); -}); diff --git a/src/cockpit/389-console/js/plugins.js b/src/cockpit/389-console/js/plugins.js deleted file mode 100644 index b34d04f..0000000 --- a/src/cockpit/389-console/js/plugins.js +++ /dev/null @@ -1,24 +0,0 @@ -$(document).ready( function() { - $("#plugin-content").load("plugins.html", function () { - $('#plugin-table').DataTable ( { - "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]], - "bAutoWidth": false, - "dom": '<"pull-left"f><"pull-right"l>tip', - "language": { - "emptyTable": "No plugins", - "search": "Search Plugins" - }, - "columnDefs": [ { - "targets": 3, - "orderable": false - } ] - }); - - $("#plugin-tab").on("click", function() { - $(".all-pages").hide(); - $("#plugin-content").show(); - }); - // Page is loaded, mark it as so... - plugin_page_loaded = 1; - }); -}); diff --git a/src/cockpit/389-console/js/replication.js b/src/cockpit/389-console/js/replication.js deleted file mode 100644 index eb378ff..0000000 --- a/src/cockpit/389-console/js/replication.js +++ /dev/null @@ -1,2192 +0,0 @@ -var repl_suffix = ""; -var prev_repl_role = "no-repl"; -var prev_role_button; -var binddn_list_color = ""; -var repl_mgr_table; -var current_role = ""; -var current_rid = ""; -var repl_agmt_table; -var repl_winsync_agmt_table; -var repl_clean_table; -var repl_agmt_values = {}; -var repl_winsync_agmt_values = {}; -var frac_prefix = "(objectclass=*) $ EXCLUDE"; -var agmt_init_intervals = []; -var agmt_init_counter = 0; -var winsync_init_intervals = []; -var winsync_init_counter = 0; - -// HTML items -var progress_html = '

Initializing Agreement...

'; - -var agmt_action_html = - ''; - -var winsync_agmt_action_html = - ''; - -var cleanallruv_action_html = - ''; - -// Attribute to CLI argument mappings -var repl_attr_map = { - 'nsds5replicaid': '--replica-id', - 'nsds5replicapurgedelay': '--repl-purge-delay', - 'nsds5replicatombstonepurgeinterval': '--repl-tombstone-purge-interval', - 'nsds5replicaprecisetombstonepurging': '--repl-fast-tombstone-purging', - 'nsds5replicabinddngroup': '--repl-bind-group', - 'nsds5replicabinddngroupcheckinterval': '--repl-bind-group-interval', - 'nsds5replicaprotocoltimeout': '--repl-protocol-timeout', - 'nsds5replicabackoffmin': '--repl-backoff-min', - 'nsds5replicabackoffmax': '--repl-backoff-max', - 'nsds5replicareleasetimeout': '--repl-release-timeout', - 'nsds5flags': '', - 'nsds5replicatype': '', - 'nsds5replicabinddn': '', - 'nsslapd-changelogdir': '--cl-dir', - 'nsslapd-changelogmaxentries': '--max-entries', - 'nsslapd-changelogmaxage': '--max-age', - 'nsslapd-changelogcompactdb-interval': '--compact-interval', - 'nsslapd-changelogtrim-interval': '--trim-interval' -}; - -var repl_cl_attrs = ['nsslapd-changelogdir', 'nsslapd-changelogmaxentries', 'nsslapd-changelogmaxage', - 'nsslapd-changelogcompactdb-interval', 'nsslapd-changelogtrim-interval']; - -var repl_attrs = ['nsds5replicaid', 'nsds5replicapurgedelay', 'nsds5replicatombstonepurgeinterval', - 'nsds5replicaprecisetombstonepurging', 'nsds5replicabinddngroup', - 'nsds5replicabinddngroupcheckinterval', 'nsds5replicaprotocoltimeout', 'nsds5replicabackoffmin', - 'nsds5replicabackoffmax', 'nsds5replicareleasetimeout']; - - -// Helper functions -function clear_agmt_wizard () { - // Clear input fields and reset dropboxes - $('.ds-agmt-schedule-checkbox').prop('checked', false); - $('#agmt-schedule-checkbox').prop('checked', true); - $("#agmt-start-time").val("00:00"); - $("#agmt-end-time").val("00:15"); - $(".ds-agmt-wiz-dropdown").prop('selectedIndex',0); - $(".ds-agmt-panel").css('display','none'); - $(".agmt-form-input").css("border-color", "initial"); - $(".agmt-form-input").val(""); - $('#frac-exclude-list').find('option').remove(); - $('#frac-exclude-tot-list').find('option').remove(); - $('#frac-strip-list').find('option').remove(); - load_schema_objects_to_select('attributetypes', 'select-attr-list'); - $("#select-attr-list").prop('selectedIndex',-1); - $("#init-options").prop("selectedIndex", 0); - $("#init-agmt-dropdown").show(); - $("#agmt-wizard-title").html("Create Replication Agreement"); -}; - -function clear_enable_repl_form () { - $("#nsds5replicaid-form").css("border-color", "initial"); - $("#nsds5replicaid-form").val(""); - $("#select-enable-repl-role").prop("selectedIndex", 0); - $("#enable-repl-pw").val(""); - $("#enable-repl-pw-confirm").val(""); - $("#enable-repl-mgr-dn").val(""); - $("#enable-repl-mgr-checkbox").prop('checked', false); - $("#enable-repl-mgr-passwd").hide(); -} - -function clear_winsync_agmt_wizard() { - // Clear out winsync agreement form - $("#winsync-agmt-cn").val(""); - $("#winsync-nsds7windowsdomain").val(""); - $("#winsync-nsds5replicahost").val(""); - $("#winsync-nsds5replicaport").val(""); - $("#winsync-nsds7windowsreplicasubtree").val(""); - $("#winsync-nsds7directoryreplicasubtree").val(""); - $("#winsync-nsds7newwinusersyncenabled-checkbox").prop('checked', false); - $("#winsync-nsds7newwingroupsyncenabled-checkbox").prop('checked', false); - $("#winsync-init-checkbox").prop('checked', false); - $("#winsync-init-chbx").show(); - $("#winsync-nsds5replicabinddn").val(""); - $("#winsync-nsds5replicacredentials").val(""); - $("#winsync-nsds5replicacredentials-confirm").val(""); - $("#winsync-nsds5replicatransportinfo").prop('selectedIndex', 0); - $("#winsync-agmt-wizard-title").html("Create Winsync Agreement"); -} - -function clear_cleanallruv_form () { - // Clear input fields and reset dropboxes - $('#force-clean').prop('checked', true); - $("#cleanallruv-rid").val(""); -}; - -function clear_repl_mgr_form () { - $("#add-repl-pw").val(""); - $("#add-repl-pw-confirm").val(""); - $("#add-repl-mgr-dn").val("cn=replication manager,cn=config"); - $("#add-repl-mgr-checkbox").prop('checked', false); - $("#add-repl-mgr-passwd").hide(); -} - - -function add_repl_mgr(dn){ - // First check if manager is set to none - $("#repl-mgr-table tbody").append( - ""+ - "" + dn +""+ - ""+ - "" + - ""); -}; - - -function do_agmt_init(suffix, agmt_cn, idx) { - var status_cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'init-status', '--suffix=' + suffix, '"' + agmt_cn + '"' ]; - log_cmd('do_agmt_init', 'Get initialization status for agmt', status_cmd); - cockpit.spawn(status_cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - var init_stat = JSON.parse(data); - if (init_stat == 'Agreement successfully initialized.' || - init_stat == 'Agreement initialization failed.') - { - // Init is done (good or bad) - get_and_set_repl_agmts(); - clearInterval(agmt_init_intervals[idx]); - } - }); -} - -function do_winsync_agmt_init(suffix, agmt_cn, idx) { - var status_cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-winsync-agmt', 'init-status', '--suffix=' + suffix, '"' + agmt_cn + '"' ]; - log_cmd('do_winsync_agmt_init', 'Get initialization status for agmt', status_cmd); - cockpit.spawn(status_cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - var init_stat = JSON.parse(data); - if (init_stat == 'Agreement successfully initialized.' || - init_stat == 'Agreement initialization failed.') - { - // Init is done (good or bad) - get_and_set_repl_winsync_agmts(); - clearInterval(agmt_init_intervals[idx]); - } - }); -} - -function get_and_set_repl_winsync_agmts() { - /* - * Get the replication agreements for the selected suffix - */ - var suffix = $("#select-repl-winsync-suffix").val(); - repl_winsync_agmt_table.clear(); - - if (suffix) { - console.log("Loading winsync replication agreements..."); - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-winsync-agmt', 'list', '--suffix=' + suffix ]; - log_cmd('get_and_set_repl_winsync_agmts', 'Get the winsync agmts', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - var obj = JSON.parse(data); - for (var idx in obj['items']) { - var state = "Enabled"; - var con_host = ""; - var con_port = ""; - var ds_subtree = ""; - var win_subtree = ""; - agmt_attrs = obj['items'][idx]['attrs']; - var agmt_name = agmt_attrs['cn'][0]; - - // Compute state (enabled by default) - if ('nsds5replicaenabled' in agmt_attrs) { - if (agmt_attrs['nsds5replicaenabled'][0].toLowerCase() == 'off'){ - state = "Disabled"; - } - } - var ws_agmt_init_status = "Initialized"; - if ('nsds5replicalastinitstatus' in agmt_attrs && - agmt_attrs['nsds5replicalastinitstatus'][0] != "") - { - ws_agmt_init_status = agmt_attrs['nsds5replicalastinitstatus'][0]; - if (ws_agmt_init_status == "Error (0) Total update in progress" || - ws_agmt_init_status == "Error (0)") - { - ws_agmt_init_status = progress_html; - var ws_interval_agmt_name = agmt_name; - var ws_init_status_interval = setInterval(function() { - var status_cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-winsync-agmt', 'init-status', '--suffix=' + suffix, '"' + ws_interval_agmt_name + '"' ]; - log_cmd('get_and_set_repl_winsync_agmts', 'Get initialization status for winsync agmt', status_cmd); - cockpit.spawn(status_cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - var init_stat = JSON.parse(data); - if (init_stat == 'Agreement successfully initialized.' || - init_stat == 'Agreement initialization failed.') - { - // Init is done (good or bad) - get_and_set_repl_winsync_agmts(); - clearInterval(ws_init_status_interval); - } - }); - }, 2000); - } else if (ws_agmt_init_status == "Error (0) Total update succeeded") { - ws_agmt_init_status = "Initialized"; - } - } else if (agmt_attrs['nsds5replicalastinitstart'][0] == "19700101000000Z"){ - ws_agmt_init_status = "Not initialized"; - } - - repl_winsync_agmt_table.row.add( [ - agmt_attrs['cn'][0], - agmt_attrs['nsds5replicahost'][0], - agmt_attrs['nsds5replicaport'][0], - state, - agmt_attrs['nsds5replicalastupdatestatus'][0], - ws_agmt_init_status, - winsync_agmt_action_html - ] ).draw( false ); - console.log("Finished loading winsync replication agreements."); - } - }); - } // suffix -} - - -function get_and_set_repl_agmts () { - /* - * Get the replication agreements for the selected suffix - */ - var suffix = $("#select-repl-agmt-suffix").val(); - - if (suffix) { - console.log("Loading replication agreements..."); - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'list', '--suffix=' + suffix ]; - log_cmd('get_and_set_repl_agmts', 'Get replication agreements', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - repl_agmt_table.clear().draw(); - var obj = JSON.parse(data); - for (var idx in obj['items']) { - agmt_attrs = obj['items'][idx]['attrs']; - var agmt_name = agmt_attrs['cn'][0]; - var state = "Enabled"; - var update_status = ""; - var agmt_init_status = "Initialized"; - - // Compute state (enabled by default) - if ('nsds5replicaenabled' in agmt_attrs) { - if (agmt_attrs['nsds5replicaenabled'][0].toLowerCase() == 'off'){ - state = "Disabled"; - } - } - - // Check for status msgs - if ('nsds5replicalastupdatestatus' in agmt_attrs) { - update_status = agmt_attrs['nsds5replicalastupdatestatus'][0]; - } - if ('nsds5replicalastinitstatus' in agmt_attrs && - agmt_attrs['nsds5replicalastinitstatus'][0] != "") - { - agmt_init_status = agmt_attrs['nsds5replicalastinitstatus'][0]; - if (agmt_init_status == "Error (0) Total update in progress" || - agmt_init_status == "Error (0)") - { - agmt_init_status = progress_html; - var interval_agmt_name = agmt_name; - var init_idx = agmt_init_counter; - agmt_init_counter += 1; - agmt_init_intervals[init_idx] = setInterval( do_agmt_init, 2000, suffix, interval_agmt_name, init_idx); - } else if (agmt_init_status == "Error (0) Total update succeeded") { - agmt_init_status = "Initialized"; - } - } else if (agmt_attrs['nsds5replicalastinitstart'][0] == "19700101000000Z"){ - agmt_init_status = "Not initialized"; - } - - // Update table - repl_agmt_table.row.add( [ - agmt_attrs['cn'][0], - agmt_attrs['nsds5replicahost'][0], - agmt_attrs['nsds5replicaport'][0], - state, - update_status, - agmt_init_status, - agmt_action_html - ] ).draw( false ); - } - console.log("Finished loading replication agreements."); - }).fail(function () { - repl_agmt_table.clear().draw(); - }); - } // suffix -} - - -function get_and_set_cleanallruv() { - console.log("Loading replication tasks..."); - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-tasks', 'list-cleanallruv']; - log_cmd('get_and_set_cleanallruv', 'Get the cleanAllRUV tasks', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - var tasks = JSON.parse(data); - repl_clean_table.clear().draw(); - for (var idx in tasks['items']) { - task_attrs = tasks['items'][idx]['attrs']; - // Update table - var abort_btn = cleanallruv_action_html; - if (task_attrs['nstaskstatus'][0].includes('Successfully cleaned rid') ){ - abort_btn = "Task Complete"; - } else if (task_attrs['nstaskstatus'][0].includes('Task aborted for rid') ){ - abort_btn = "Task Aborted"; - } - repl_clean_table.row.add( [ - task_attrs['cn'][0], - get_date_string(task_attrs['createtimestamp'][0]), - task_attrs['replica-base-dn'][0], - task_attrs['replica-id'][0], - task_attrs['nstaskstatus'][0], - abort_btn - ] ); - } - repl_clean_table.draw(false); - console.log("Finished loading replication tasks."); - }); -} - - -function get_and_set_repl_config () { - var suffix = $("#select-repl-cfg-suffix").val(); - - if (suffix) { - $("#nsds5replicaid").css("border-color", "initial"); - repl_config_values = {}; - console.log("Loading replication configuration..."); - - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'get', '--suffix=' + suffix ]; - log_cmd('get_and_set_repl_config', 'Get replication configuration', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - var repl = JSON.parse(data); - var repl_type; - var repl_flags; - var manager = false; - $('#repl-mgr-table').find("tr:gt(0)").remove(); - $(".ds-cfg").val(""); - $("#nsds5replicaprecisetombstonepurging").prop('checked', false); - - // Set configuration and the repl manager table - for (var attr in repl['attrs']) { - var vals = repl['attrs'][attr]; - attr = attr.toLowerCase(); - - if (attr in repl_attr_map) { - if (attr == "nsds5replicabinddn") { - // update manager table - for (var val_idx in vals){ - add_repl_mgr(vals[val_idx]); - manager = true; - } - } else if (attr == "nsds5replicatype") { - repl_type = vals[0]; - } else if (attr == "nsds5flags") { - repl_flags = vals[0]; - } else { - // Regular attribute - if (vals[0] == "on") { - $("#" + attr).prop('checked', true); - $("#" + attr).trigger('change'); - } else if (vals[0] == "off") { - $("#" + attr).prop('checked', false); - $("#" + attr).trigger('change'); - } - $("#" + attr ).val(vals[0]); - repl_config_values[attr] = vals[0]; - } - } - } - if (!manager) { - // Add an empty row to define the table - $("#repl-mgr-table tbody").append( - ""+ - "None"+ - "" + - ""); - } - - // Set the replica role - if (repl_type == "3"){ - $("#select-repl-role").val("Master"); - current_role = "Master"; - $("#nsds5replicaid").show(); - $("#replicaid-label").show(); - } else { - $("#nsds5replicaid").hide(); - $("#replicaid-label").hide(); - if (repl_flags == "1"){ - $("#select-repl-role").val("Hub"); - current_role = "Hub"; - } else { - $("#select-repl-role").val("Consumer"); - current_role = "Consumer"; - } - } - current_rid = $("#nsds5replicaid").val(); - - // Show the page (in case it was hidden) - $("#ds-repl-enabled").hide(); - $("#repl-config-content").show(); - - console.log("Finished loading replication configuration."); - }).fail(function(data) { - // No replication - current_role = "Disabled"; - $("#repl-config-content").hide(); - $("#ds-repl-enabled").show(); - }); - } else { - // No Suffix - $("#repl-config-content").hide(); - $("#ds-repl-enabled").hide(); - } - - // Do the changelog settings - $("#cl-create-div").show(); - $("#cl-del-div").hide(); - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'get-changelog']; - log_cmd('get_and_set_repl_config', 'Get replication changelog', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - $(".ds-cl").val(""); // Clear form - var cl = JSON.parse(data); - repl_cl_values = {}; - for (var attr in cl['attrs']) { - var val = cl['attrs'][attr][0]; - attr = attr.toLowerCase(); - $("#" + attr ).val(val); - $("#cl-create-div").hide(); - $("#cl-del-div").show(); - repl_cl_values[attr] = val; - } - }).fail(function() { - // No changelog, clear the form - $(".ds-cl").val(""); - }); -} - - -function save_repl_config(suffix, ignore_rid) { - /* - * Check for changes in the replication settings - */ - var set_repl_values = {}; - var set_cl_values = {}; - var arg_list = []; - for (var attr in repl_attrs) { - attr = repl_attrs[attr]; - var val = ""; - if ( $("#" + attr).is(':checkbox')) { - if ( $("#" + attr).is(":checked")) { - val = "on"; - } else { - val = "off"; - } - } else { - val = $("#" + attr).val(); - } - var prev_val = ""; - - if (attr in repl_config_values) { - prev_val = repl_config_values[attr]; - } - - if (val != prev_val) { - if (attr == "nsds5replicaid"){ - // skip it since we are doing a promotion - continue; - } - // Handle checkbox input - if ( $("#" + attr).is(':checkbox')) { - if ( $("#" + attr).is(":checked")) { - arg_list.push(repl_attr_map[attr] + "=" + "on" ); - } else { - // Not checked - arg_list.push(repl_attr_map[attr] + "=" + "off" ); - } - } else { - // Regular input - if (val != "") { - // Regular setting - add to the list - arg_list.push(repl_attr_map[attr] + "=" + val ); - } else { - // removed - arg_list.push(repl_attr_map[attr] + "="); - } - } - set_repl_values[attr] = val; - } - } - - /* - * Check for changes in the changelog settings - */ - var arg_cl_list = []; - for (var attr in repl_cl_attrs) { - attr = repl_cl_attrs[attr]; - var val = $("#" + attr).val(); - var prev_val = ""; - if (attr in repl_cl_values) { - prev_val = repl_cl_values[attr]; - } - if (val != prev_val) { - // we have a difference - if (val != "") { - // Regular setting -add to the list - arg_cl_list.push(repl_attr_map[attr] + "=" + val); - } else { - // removed - arg_cl_list.push(repl_attr_map[attr] + "="); - } - set_cl_values[attr] = val; - } - } - - /* - * Save repl config settings - */ - if (arg_list.length > 0){ - - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'set', '--suffix=' + suffix ]; - cmd = cmd.concat(arg_list); - log_cmd('save_repl_config', 'Set replication configuration', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - popup_success('Saved replication configuration'); - for (var key in set_repl_values) { - // Update current in memory values - repl_config_values[key] = set_repl_values[key]; - } - /* - * Save changelog settings - */ - if (arg_cl_list.length > 0){ - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication' ,'set-changelog']; - cmd = cmd.concat(arg_cl_list); - log_cmd('save_repl_config', 'Set changelog configuration', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - popup_success('Saved changelog configuration'); - for (var key in set_cl_values) { - // Update current in memory values - repl_cl_values[key] = set_cl_values[key]; - } - get_and_set_repl_config(); - }).fail(function(data) { - get_and_set_repl_config(); - popup_err("Failed to save changelog configuration", data.message); - }); - } else { - // No changelog changes, so we're done, refresh the settings - get_and_set_repl_config(); - } - }).fail(function(data) { - // Restore prev values - get_and_set_repl_config(); - popup_err("Failed to set replication configuration", data.message); - }); - } else if (arg_cl_list.length > 0) { - /* - * Only changelog settings need to be applied - */ - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication' ,'set-changelog']; - cmd = cmd.concat(arg_cl_list); - log_cmd('save_repl_config', 'Set changelog configuration', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - popup_success('Saved changelog configuration'); - for (var key in set_cl_values) { - // Update current in memory values - repl_cl_values[key] = set_cl_values[key]; - } - get_and_set_repl_config(); - }).fail(function(data) { - get_and_set_repl_config(); - popup_err("Failed to save changelog configuration", data.message); - }); - } -} - - -/* - * Load the replication page, and set the handlers - */ -$(document).ready( function() { - $("#replication-content").load("replication.html", function () { - // Set up agreement table - repl_agmt_table = $('#repl-agmt-table').DataTable( { - "paging": true, - "bAutoWidth": false, - "dom": '<"pull-left"f><"pull-right"l>tip', - "lengthMenu": [ 10, 25, 50, 100], - "language": { - "emptyTable": "No agreements configured", - "search": "Search Agreements" - }, - "columnDefs": [ { - "targets": 6, - "orderable": false - } ], - "columns": [ - { "width": "20%" }, - { "width": "20%" }, - { "width": "50px" }, - { "width": "50px" }, - { "width": "20%" }, - { "width": "20%" }, - { "width": "130px" } - ], - }); - - // Set up windows sync agreement table - repl_winsync_agmt_table = $('#repl-winsync-agmt-table').DataTable( { - "paging": true, - "bAutoWidth": false, - "dom": '<"pull-left"f><"pull-right"l>tip', - "lengthMenu": [ 10, 25, 50, 100], - "language": { - "emptyTable": "No winsync agreements configured", - "search": "Search Agreements" - }, - "columnDefs": [ { - "targets": 6, - "orderable": false - } ] - }); - - // Set up CleanAllRUV Table - repl_clean_table = $('#repl-clean-table').DataTable( { - "paging": true, - "searching": false, - "bAutoWidth": false, - "dom": 'B<"pull-left"f><"pull-right"l>tip', - buttons: [ - { - text: 'Refresh Task List', - action: function ( e, dt, node, config ) { - console.log("hmmm"); - get_and_set_cleanallruv(); - } - } - ], - "lengthChange": false, - "language": { - "emptyTable": "No CleanAllRUV tasks", - }, - "columnDefs": [ { - "targets": 5, - "orderable": false - } ] - }); - - binddn_list_color = $("#repl-managers-list").css("border-color"); - - // Load existing replication config (if any), set role, etc - - $("#schedule-settings").hide(); - - $("#repl-config-btn").on("click", function() { - $(".all-pages").hide(); - $("#replication-content").show(); - $("#repl-config").show(); - }); - - $("#repl-agmts-btn").on("click", function() { - $(".all-pages").hide(); - $("#replication-content").show(); - $("#repl-agmts").show(); - }); - - $("#repl-winsync-btn").on("click", function() { - $(".all-pages").hide(); - $("#replication-content").show(); - $("#repl-winsync").show(); - }); - $("#repl-cleanallruv-btn").on("click", function() { - $(".all-pages").hide(); - $("#replication-content").show(); - $("#repl-cleanallruv").show(); - }); - - $("#select-repl-cfg-suffix").on("change", function() { - get_and_set_repl_config(); - }); - - $("#select-repl-agmt-suffix").on("change", function() { - get_and_set_repl_agmts(); - }); - - $("#select-repl-winsync-suffix").on("change", function() { - get_and_set_repl_winsync_agmts(); - }); - - $("#select-repl-role").on("change", function() { - var new_role = $(this).val(); - if (new_role == "Master"){ - if (current_role != new_role) { - // Reset replica ID for a new master - $("#nsds5replicaid").val("0"); - } - $("#nsds5replicaid").show(); - $("#replicaid-label").show(); - $("#repl-config-content").show(); - } else { - $("#nsds5replicaid").hide(); - $("#replicaid-label").hide(); - $("#repl-config-content").show(); - $("#nsds5replicaid").css("border-color", "initial"); - } - }); - - $("#enable-repl-btn").on('click', function () { - clear_enable_repl_form(); - }); - - /* - * Enable replication - select role dynamics - */ - $("#select-enable-repl-role").on("change", function() { - var new_role = $(this).val(); - if (new_role == "Master"){ - $("#repl-rid-form").show(); - } else { - $("#repl-rid-form").hide(); - } - }); - /* - * Enable replication - save it - */ - $("#enable-repl-save").on('click', function () { - var suffix = $("#select-repl-cfg-suffix").val(); - var role = $("#select-enable-repl-role").val(); - var repl_dn = $("#enable-repl-mgr-dn").val(); - var repl_pw = $("#enable-repl-pw").val(); - var repl_pw_confirm = $("#enable-repl-pw-confirm").val(); - var repl_group = $("#enable-bindgroupdn").val(); - var cmd = []; - - // Validate all the inputs - if (role == "Master") { - // Master role, get and valid replica id - var rid = $("#nsds5replicaid-form").val(); - if (rid == ""){ - $("#nsds5replicaid-form").css("border-color", "red"); - popup_msg("Missing Replica ID", - "A Master replica requires a unique identifier. " + - "Please enter a value for Replica ID between 1 and 65534"); - return; - } - if (valid_num(rid)){ - if (rid < 1 || rid >= 65535){ - $("#nsds5replicaid-form").css("border-color", "red"); - popup_msg("Invalid Replica ID", - "A Master replica requires a unique identifier. " + - "Please enter a value for Replica ID between 1 and 65534"); - return; - } - } else { - $("#nsds5replicaid-form").css("border-color", "red"); - popup_msg("Replica ID is not a number", - "A Master replica requires a unique identifier. " + - "Please enter a value for Replica ID between 1 and 65534"); - return; - } - $("#nsds5replicaid-form").css("border-color", "initial"); - cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'enable', - '--suffix=' + suffix, '--role=' + role, '--replica-id=' + rid]; - } else { - // Hub or Consumer - must have a bind dn/group - if (repl_dn == "" && repl_group == ""){ - popup_msg("Attention!", "Replication Manager or Replication Bind Group is required"); - return; - } - cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'enable', - '--suffix=' + suffix, '--role=' + role]; - } - - if (repl_dn != ''){ - if (repl_pw != repl_pw_confirm) { - popup_msg("Attention!", "Passwords do not match"); - $("#enable-repl-pw").val(""); - $("#enable-repl-pw-confirm").val(""); - return; - } - if (!valid_dn(repl_dn)) { - popup_msg("Attention!", "Invalid DN for Replication Manager"); - return; - } - cmd.push.apply(cmd, ['--bind-dn=' + repl_dn]); - cmd.push.apply(cmd, ['--bind-passwd=' + repl_pw]); - } - if (repl_group != ""){ - if (!valid_dn(repl_group)){ - popup_msg("Attention!", "Invalid DN for Replication Bind Group"); - return; - } - cmd.push.apply(cmd, ['--bind-group-dn=' + repl_group]); - } - - // Enable replication finally - log_cmd('#enable-repl-save (click)', 'Enable replication', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - // Replication has been enabled - popup_success("Successfully enabled replication"); - $("#enable-repl-form").modal('toggle'); - get_and_set_repl_config(); - }).fail(function(data) { - // Undo what we have done - popup_err("Failed to enable replication", data.message); - var disable_cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'disable', '--suffix=' + suffix ]; - log_cmd('#enable-repl-save (click)', 'Disable replication after error', disable_cmd); - cockpit.spawn(disable_cmd, { superuser: true, "err": "message", "environ": [ENV]}).always(function(data) { - get_and_set_repl_config(); - $("#enable-repl-form").modal('toggle'); - }); - }); - }); - - /* - * Disable replication - */ - $("#disable-repl-btn").on('click', function () { - var suffix = $("#select-repl-cfg-suffix").val(); - popup_confirm("Are you sure you want to disable replication? This will remove all your replication agreements and can not be undone!", "Confirmation", function (yes) { - if (yes) { - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'disable', '--suffix=' + suffix ]; - log_cmd('#disable-repl-btn (click)', 'Disable replication', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - current_role = "Disabled"; - $("#repl-config-content").hide(); - popup_success('Successfully disabled replication'); - get_and_set_repl_config(); - }).fail(function(data) { - popup_err("Failed to disable replication", data.message); - get_and_set_repl_config(); - }); - } - }); - }); - - /* - * Save replication configuration - */ - $("#repl-config-save").on('click', function () { - var suffix = $("#select-repl-cfg-suffix").val(); - var rid = $("#nsds5replicaid").val(); - - if (suffix) { - /* - * Did we config change, promote, or demote this replica? - */ - var new_role = $("#select-repl-role").val(); - if (new_role != current_role) { - /* - * Promote/demote the replica - */ - popup_confirm("Are you sure you want to change the replication role to \"" + new_role + "\"?", "Confirmation", function (yes) { - if (yes) { - if (new_role == "Master"){ - /* - * Promote to Master - */ - if ( !valid_num(rid) ) { - popup_msg("Invalid Replica ID", - "A Master replica requires a unique numerical identifier. Please enter a value for Replica ID between 1 and 65534"); - get_and_set_repl_config(); - return; - } - var rid_num = parseInt(rid, 10); - if (rid_num < 1 || rid_num >= 65535){ - popup_msg("Missing Required Replica ID", - "A Master replica requires a unique numerical identifier. Please enter a value for Replica ID between 1 and 65534"); - get_and_set_repl_config(); - return; - } - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'promote', - '--suffix=' + suffix, "--newrole=" + new_role, "--replica-id=" + rid]; - log_cmd('#repl-config-save (click)', 'Promote replica to Master', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - current_role = "Master";; - popup_success('Successfully promoted replica to a Master'); - get_and_set_repl_config(); - save_repl_config(suffix, true); - }).fail(function(data) { - popup_err("Failed to promote replica to a Master", data.message); - get_and_set_repl_config(); - }); - } else if (new_role == "Hub" && current_role == "Master"){ - /* - * Demote to Hub, but first check that we have a replication manager - */ - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'get', '--suffix=' + suffix ]; - log_cmd('get_and_set_repl_config', 'Get replication configuration', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - var repl = JSON.parse(data); - var manager = false; - for (var attr in repl['attrs']) { - if (attr.toLowerCase() == "nsds5replicabinddn") { - manager = true; - break; - } - } - if (manager == false) { - popup_msg("Missing Required Setting", - "You must create a replication manager before you can demote this replica to a Hub"); - return; - } - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'demote', - '--suffix=' + suffix, "--newrole=" + new_role]; - log_cmd('#repl-config-save (click)', 'Demote replica to Hub', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - current_role = "Hub"; - popup_success('Successfully demoted replica to a Hub'); - save_repl_config(suffix, true); - }).fail(function(data) { - popup_err("Failed to demote replica to a Hub", data.message); - get_and_set_repl_config(); - }); - }); - } else if (new_role == "Hub" && current_role == "Consumer"){ - /* - * Promote to Hub - */ - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'promote', - '--suffix=' + suffix, "--newrole=" + new_role]; - log_cmd('#repl-config-save (click)', 'Promote replica to Hub ', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - current_role = "Hub";; - popup_success('Successfully promoted replica to a Hub'); - save_repl_config(suffix, true); - }).fail(function(data) { - popup_err("Failed to promote replica to a Hub", data.message); - get_and_set_repl_config(); - }); - } else { - /* - * Demote to Consumer, but first confirm we have a replication manager - */ - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'get', '--suffix=' + suffix ]; - log_cmd('get_and_set_repl_config', 'Get replication configuration', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - var repl = JSON.parse(data); - var manager = false; - for (var attr in repl['attrs']) { - if (attr.toLowerCase() == "nsds5replicabinddn") { - manager = true; - break; - } - } - if (manager == false) { - popup_msg("Missing Required Setting", - "You must create a replication manager before you can demote this replica to a Consumer."); - return; - } - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'demote', - '--suffix=' + suffix, "--newrole=" + new_role]; - log_cmd('#repl-config-save (click)', 'Demote replication to Consumer', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - current_role = "Consumer"; - popup_success('Successfully demoted replica to a Consumer'); - save_repl_config(suffix, true); - }).fail(function(data) { - popup_err("Failed to demote replica to a Consumer", data.message); - get_and_set_repl_config(); - }); - }); - } - } else { - // Not changing the role - reset the dropdown - $("#select-repl-role").val(current_role); - get_and_set_repl_config(); - } - }); // popup_confirm - } else { - /* - * We did NOT promote/demote, etc. This was just a configuration change... - */ - save_repl_config(suffix, false); - } - } // Suffix - }); - - // Create changelog - $("#create-cl-btn").on('click', function () { - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication' ,'create-changelog']; - log_cmd('#create-cl-btn (click)', 'Create replication changelog', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - get_and_set_repl_config(); - popup_success('Successfully created replication changelog'); - }).fail(function(data) { - get_and_set_repl_config(); - popup_err("Failed to create replication changelog", data.message); - }); - }); - - // Remove changelog - $("#delete-cl-btn").on('click', function () { - popup_confirm("Are you sure you want to delete the replication changelog as it will break all the existing agreements?", "Confirmation", function (yes) { - if (yes) { - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication' ,'delete-changelog']; - log_cmd('#delete-cl-btn (click)', 'Delete replication changelog', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - get_and_set_repl_config(); - popup_success('Successfully removed replication changelog'); - }).fail(function(data) { - get_and_set_repl_config(); - popup_err("Failed to remove replication changelog", data.message); - }); - } - }); - }); - - // Save Repl Agreement Wizard - $("#agmt-save").on("click", function() { - // Get all the settings - var suffix = $("#select-repl-agmt-suffix").val(); - var cmd = []; - var cmd_args = []; - var param_err = false; - var agmt_name = $("#agmt-cn").val(); - var agmt_host = $("#nsds5replicahost").val(); - var agmt_port = $("#nsds5replicaport").val(); - var agmt_bind = $("#nsds5replicabinddn").val(); - var agmt_bindpw = $("#nsds5replicacredentials").val(); - var agmt_bindpw_confirm = $("#nsds5replicacredentials-confirm").val(); - var agmt_conn = $("#nsds5replicatransportinfo").val(); - var agmt_method = $("#nsds5replicabindmethod").val(); - var agmt_schedule = ""; - var agmt_init = $("#init-options").val(); - var agmt_exclude = ""; - var agmt_tot_exclude = ""; - var agmt_strip = ""; - var editing = false; - var init_replica = false; - - if ($("#agmt-wizard-title").text().includes('Edit') ) { - editing = true; - } - - // Check required settings - if ( agmt_port == "") { - $("#nsds5replicaport").css("border-color", "red"); - param_err = true; - } else { - $("#nsds5replicaport").css("border-color", "initial"); - cmd_args.push("--port=" + agmt_port); - } - if ( agmt_host == "") { - $("#nsds5replicahost").css("border-color", "red"); - param_err = true; - } else { - $("#nsds5replicahost").css("border-color", "initial"); - cmd_args.push('--host=' + agmt_host); - } - if ( agmt_conn == "") { - $("#nsds5replicatransportinfo").css("border-color", "red"); - param_err = true; - } else { - $("#nsds5replicatransportinfo").css("border-color", "initial"); - cmd_args.push('--conn-protocol=' + agmt_conn); - } - if ( agmt_method == "") { - $("#nsds5replicabindmethod").css("border-color", "red"); - param_err = true; - } else { - $("#nsds5replicabindmethod").css("border-color", "initial"); - cmd_args.push('--bind-method=' + agmt_method); - } - if ( agmt_bind == "") { - $("#nsds5replicabinddn").css("border-color", "red"); - param_err = true; - } else { - $("#nsds5replicabinddn").css("border-color", "initial"); - cmd_args.push('--bind-dn=' + agmt_bind); - } - if (param_err ){ - popup_msg("Error", "Missing required parameters"); - return; - } - - /* - * Handle the optional settings - */ - $("#frac-exclude-list option").each(function() { - agmt_exclude += $(this).val() + " "; - }); - $("#frac-exclude-tot-list option").each(function() { - agmt_tot_exclude += $(this).val() + " "; - }); - $("#frac-strip-list option").each(function() { - agmt_strip += $(this).val() + " "; - }); - - if (agmt_bindpw != agmt_bindpw_confirm) { - popup_msg("Attention!", "Passwords do not match"); - return; - } - - // Bind Password - if (!editing ){ - if (agmt_bindpw != "") { - cmd_args.push('--bind-passwd=' + agmt_bindpw); - } - } else { - if ( !('nsds5replicacredentials' in repl_agmt_values) || - agmt_bindpw != repl_agmt_values['nsds5replicacredentials']) - { - cmd_args.push('--bind-passwd="' + agmt_bindpw); - } - } - // Frac attrs - agmt_exclude = agmt_exclude.trim(); - if (!editing) { - if (agmt_exclude != "") { - cmd_args.push('--frac-list='+ agmt_exclude); - } - } else { - if ( !('nsds5replicatedattributelist' in repl_agmt_values) || - agmt_exclude != repl_agmt_values['nsds5replicatedattributelist'].replace(frac_prefix, "")) - { - cmd_args.push('--frac-list=' + frac_prefix + ' ' + agmt_exclude); - } - } - // Frac total attr - agmt_tot_exclude = agmt_tot_exclude.trim(); - if (!editing) { - if (agmt_tot_exclude != "") { - cmd_args.push('--frac-list-total='+ agmt_tot_exclude); - } - } else { - if ( !('nsds5replicatedattributelisttotal' in repl_agmt_values) || - agmt_tot_exclude != repl_agmt_values['nsds5replicatedattributelisttotal'].replace(frac_prefix, "")); - { - cmd_args.push('--frac-list-total=' + frac_prefix + ' ' + agmt_tot_exclude); - } - } - // Strip attrs - agmt_strip = agmt_strip.trim(); - if (!editing) { - if (agmt_strip != "") { - cmd_args.push('--strip-list='+ agmt_strip); - } - } else { - if ( !('nsds5replicastripattrs' in repl_agmt_values) || - agmt_strip != repl_agmt_values['nsds5replicastripattrs']); - { - cmd_args.push('--strip-list='+ agmt_strip); - } - } - - if ( !($("#agmt-schedule-checkbox").is(":checked")) ){ - agmt_start = $("#agmt-start-time").val().replace(':',''); - agmt_end = $("#agmt-end-time").val().replace(':',''); - - if (agmt_start == agmt_end) { - popup_msg("Error", "The replication start and end times can not behte same"); - return; - } - - // build the days - var agmt_days = ""; - if ( $("#schedule-sun").is(":checked") ){ - agmt_days = "0"; - } - if ( $("#schedule-mon").is(":checked") ){ - agmt_days += "1"; - } - if ( $("#schedule-tue").is(":checked") ){ - agmt_days += "2"; - } - if ( $("#schedule-wed").is(":checked") ){ - agmt_days += "3"; - } - if ( $("#schedule-thu").is(":checked") ){ - agmt_days += "4"; - } - if ( $("#schedule-fri").is(":checked") ){ - agmt_days += "5"; - } - if ( $("#schedule-sat").is(":checked") ){ - agmt_days += "6"; - } - if (agmt_days == "" ){ - popup_msg("Error", "You must set at least one day in the schedule to perform replication"); - return; - } - // Set final value - agmt_schedule = agmt_start + "-" + agmt_end + " " + agmt_days; - - if (!editing ){ - cmd_args.push('--schedule=' + agmt_schedule); - } else { - if ( !('nsds5replicaupdateschedule' in repl_agmt_values) || - agmt_schedule != repl_agmt_values['nsds5replicaupdateschedule'] ) - { - cmd_args.push('--schedule=' + agmt_schedule); - } - } - } else { - // if "sync all the time" is checked, might need to remove the schedule attribute - if ('nsds5replicaupdateschedule' in repl_agmt_values) { - cmd_args.push('--schedule='); - } - } - if (agmt_init == "online-init") { - init_replica = true; - } - if ( agmt_name == "") { - $("#agmt-cn").css("border-color", "red"); - param_err = true; - } else { - $("#agmt-cn").css("border-color", "initial"); - cmd_args.push('"' + agmt_name + '"'); - } - - // Create agreement in DS - if ( editing ) { - cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'set', '--suffix=' + suffix ]; - } else { - cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'create', '--suffix=' + suffix]; - } - cmd = cmd.concat(cmd_args); - log_cmd('#agmt-save (click)', 'Create/Set replication agreement', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - if (editing){ - popup_success('Successfully edited replication agreement'); - } else { - popup_success('Successfully created replication agreement'); - } - if (init_replica) { - // Launch popup stating initialization has begun - var init_cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'init', '--suffix=' + suffix, agmt_name ]; - log_cmd('#agmt-save (click)', 'Initialize agreement', init_cmd); - cockpit.spawn(init_cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function() { - get_and_set_repl_agmts(); - }).fail(function(data) { - popup_err("Failed to initialize replication agreement", data.message); - }); - } else { - get_and_set_repl_agmts(); - } - }).fail(function(data) { - if (editing) { - popup_err("Failed to edit replication agreement", data.message); - } else { - popup_err("Failed to create replication agreement", data.message); - } - }); - - // Done, close the form - $("#agmt-form").modal('toggle'); - clear_agmt_wizard(); - }); - - /* - * Initialize agreement - */ - $(document).on('click', '.agmt-init-btn', function(e) { - e.preventDefault(); - var suffix = $("#select-repl-agmt-suffix").val(); - var data = repl_agmt_table.row( $(this).parents('tr') ).data(); - var agmt_name = data[0]; - var row_idx = $(this).closest('tr').index(); - repl_agmt_table.cell({row: row_idx, column: 5}).data(progress_html).draw(); - - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'init', '--suffix=' + suffix, '"' + agmt_name + '"' ]; - log_cmd('.agmt-init-btn (click)', 'Initialize replication agreement', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - var init_idx = agmt_init_counter; - agmt_init_counter += 1; - agmt_init_intervals[init_idx] = setInterval( do_agmt_init, 2000, suffix, agmt_name, init_idx); - }).fail(function(data) { - get_and_set_repl_agmts(); - popup_err("Failed to initialize agreement", data.message); - }); - }); - - $(document).on('click', '.winsync-agmt-init-btn', function(e) { - e.preventDefault(); - var suffix = $("#select-repl-winsync-suffix").val(); - var data = repl_winsync_agmt_table.row( $(this).parents('tr') ).data(); - var agmt_name = data[0]; - var row_idx = $(this).closest('tr').index(); - repl_winsync_agmt_table.cell({row: row_idx, column: 5}).data(progress_html).draw(); - - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-winsync-agmt', 'init', '--suffix=' + suffix, '"' + agmt_name + '"' ]; - log_cmd('.winsync-agmt-init-btn (click)', 'Initialize replication winsync agreement', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - var init_idx = agmt_init_counter; - agmt_init_counter += 1; - agmt_init_intervals[init_idx] = setInterval( do_winsync_agmt_init, 2000, suffix, agmt_name, init_idx); - }).fail(function(data) { - get_and_set_repl_winsync_agmts(); - popup_err("Failed to initialize winsync agreement", data.message); - }); - }); - - - /* Store the repl dn from the table when opening the mgr delete confirmation modal */ - $(document).on('click', '.remove-repl-mgr', function(e) { - e.preventDefault(); - var mgr_row = $(this).parent().parent(); - var suffix = $("#select-repl-cfg-suffix").val(); - var mgr_dn = mgr_row.children("td:nth-child(1)"); - popup_confirm("Are you sure you want to delete Replication Manager: " + mgr_dn.text() + "", "Confirmation", function (yes) { - if (yes) { - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication' ,'set', - '--repl-del-bind-dn=' + mgr_dn.text(), '--suffix=' + suffix]; - log_cmd('.remove-repl-mgr (click)', 'Remove replication manager ', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - /* Remove the manager entry */ - var del_cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', - 'delete-manager', "--name=" + mgr_dn.text()]; - log_cmd('.remove-repl-mgr(click)', 'Delete replication manager entry', del_cmd); - cockpit.spawn(del_cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - popup_success('Successfully removed replication manager'); - get_and_set_repl_config(); - }); - }).fail(function(data) { - get_and_set_repl_config(); - popup_err("Failed to remove replication manager", data.message); - }); - } - }); - }); - - /* - * Delete repl agreement - */ - $(document).on('click', '.agmt-del-btn', function(e) { - e.preventDefault(); - var data = repl_agmt_table.row( $(this).parents('tr') ).data(); - var del_agmt_name = data[0]; - var agmt_row = $(this); - popup_confirm("Are you sure you want to delete replication agreement: " + del_agmt_name + "", "Confirmation", function (yes) { - if (yes) { - var suffix = $("#select-repl-agmt-suffix").val(); - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'delete', '--suffix=' + suffix, '"' + del_agmt_name + '"']; - log_cmd('.agmt-del-btn (click)', 'Delete replication agreement', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - popup_success('Successfully removed replication agreement'); - // Update table - repl_agmt_table.row( agmt_row.parents('tr') ).remove().draw( false ); - }).fail(function(data) { - get_and_set_repl_config(); - popup_err("Failed to remove replication agreement", data.message); - }); - } - }); - }); - - $(document).on('click', '.winsync-agmt-del-btn', function(e) { - e.preventDefault(); - var data = repl_winsync_agmt_table.row( $(this).parents('tr') ).data(); - var del_agmt_name = data[0]; - var agmt_row = $(this); - popup_confirm("Are you sure you want to delete replication agreement: " + del_agmt_name + "", "Confirmation", function (yes) { - if (yes) { - var suffix = $("#select-repl-agmt-suffix").val(); - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-winsync-agmt', 'delete', '--suffix=' + suffix, '"' + del_agmt_name + '"']; - log_cmd('.winsync-agmt-del-btn (click)', 'Delete replication winsync agreement', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - popup_success('Successfully removed replication winsync agreement'); - // Update table - repl_winsync_agmt_table.row( agmt_row.parents('tr') ).remove().draw( false ); - }).fail(function(data) { - get_and_set_repl_config(); - popup_err("Failed to remove replication winsync agreement", data.message); - }); - } - }); - }); - - /* - * Edit Agreement - */ - $(document).on('click', '.agmt-edit-btn', function(e) { - e.preventDefault(); - clear_agmt_wizard(); - var suffix = $("#select-repl-agmt-suffix").val(); - var data = repl_agmt_table.row( $(this).parents('tr') ).data(); - var edit_agmt_name = data[0]; - // Set agreement form values - $("#agmt-wizard-title").html("Edit Replication Agreement"); - - // Hide init dropdown - $("#init-agmt-dropdown").hide(); - - // Get agreement from DS and populate form - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'get', '--suffix=' + suffix, '"' + edit_agmt_name + '"']; - log_cmd('.agmt-edit-btn (click)', 'Edit replication agreement', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - var agmt_obj = JSON.parse(data); - var frac_attrs = ""; - var frac_tot_attrs = ""; - var strip_attrs = ""; - - $("#agmt-cn").val(edit_agmt_name); - for (var attr in agmt_obj['attrs']) { - var val = agmt_obj['attrs'][attr][0]; - attr = attr.toLowerCase(); - $("#" + attr).val(val); - repl_agmt_values[attr] = val; - } - - // Fill Password Confirm Input - if ( 'nsds5replicacredentials' in agmt_obj['attrs'] ){ - $("#nsds5replicacredentials-confirm").val(agmt_obj['attrs']["nsds5replicacredentials"][0]); - } - - // Transport info - val = agmt_obj['attrs']["nsds5replicatransportinfo"][0].toLowerCase(); - if (val == "ldap"){ - $("#nsds5replicatransportinfo").val("LDAP"); - } else if (val == "ldaps"){ - $("#nsds5replicatransportinfo").val("LDAPS"); - } else if (val == "starttls" || val == "tls"){ - $("#nsds5replicatransportinfo").val("StartTLS"); - } - - // Bind Method - val = agmt_obj['attrs']["nsds5replicabindmethod"][0].toLowerCase(); - if (val == "simple"){ - $("#nsds5replicabindmethod").val("SIMPLE"); - } else if (val == "sasl/digest-md5"){ - $("#nsds5replicabindmethod").val("SASL/DIGEST-MD5"); - } else if (val == "sasl/gssapi"){ - $("#nsds5replicabindmethod").val("SASL/GSSAPI"); - } else if (val == "sslclientauth"){ - $("#nsds5replicatransportinfo").val("SSLCLIENTAUTH"); - } - - // Load fractional lists - if ( 'nsds5replicatedattributelist' in agmt_obj['attrs'] ){ - frac_attrs = agmt_obj['attrs']['nsds5replicatedattributelist'][0]; - frac_attrs = frac_attrs.replace(frac_prefix, "").split(" "); - for(var i = 0; i < frac_attrs.length; i++) { - var opt = frac_attrs[i]; - if (opt != "") { - var option = $('').attr("value", opt).text(opt); - $("#frac-exclude-list").append(option); - } - } - } - if ( 'nsds5replicatedattributelisttotal' in agmt_obj['attrs'] ){ - frac_tot_attrs = agmt_obj['attrs']['nsds5replicatedattributelisttotal'][0]; - frac_tot_attrs = frac_tot_attrs.replace(frac_prefix, "").split(" "); - for(var i = 0; i < frac_tot_attrs.length; i++) { - var opt = frac_tot_attrs[i]; - if (opt != "") { - var option = $('').attr("value", opt).text(opt); - $("#frac-exclude-tot-list").append(option); - } - } - } - if ( 'nsds5replicastripattrs' in agmt_obj['attrs'] ){ - strip_attrs = agmt_obj['attrs']['nsds5replicastripattrs'][0]; - strip_attrs = strip_attrs.split(" "); - for(var i = 0; i < strip_attrs.length; i++) { - var opt = strip_attrs[i]; - if (opt != "") { - var option = $('').attr("value", opt).text(opt); - $("#frac-strip-list").append(option); - } - } - } - - // Set schedule - if ( 'nsds5replicaupdateschedule' in agmt_obj['attrs'] ){ - var val = agmt_obj['attrs']['nsds5replicaupdateschedule'][0]; - var parts = val.split(" "); - var days = parts[1]; - var times = parts[0].split("-"); - var start_time = times[0].substring(0,2) + ":" + times[0].substring(2,4); - var end_time = times[1].substring(0,2) + ":" + times[1].substring(2,4); - - $("#agmt-schedule-checkbox").prop('checked', false); - $('#agmt-schedule-panel *').attr('disabled', false); - $("#schedule-settings").show(); - - $("#agmt-start-time").val(start_time); - $("#agmt-end-time").val(end_time); - if ( days.indexOf('0') != -1){ // Sunday - $("#schedule-sun").prop('checked', true); - } - if ( days.indexOf('1') != -1){ // Monday - $("#schedule-mon").prop('checked', true); - } - if ( days.indexOf('2') != -1){ // Tuesday - $("#schedule-tue").prop('checked', true); - } - if ( days.indexOf('3') != -1){ // Wednesday - $("#schedule-wed").prop('checked', true); - } - if ( days.indexOf('4') != -1){ // Thursday - $("#schedule-thu").prop('checked', true); - } - if ( days.indexOf('5') != -1){ // Friday - $("#schedule-fri").prop('checked', true); - } - if ( days.indexOf('6') != -1){ // Saturday - $("#schedule-sat").prop('checked', true); - } - } - // Finally Open form - $("#agmt-form").modal('toggle'); - }).fail(function(data) { - popup_err("Failed to get replication agreement entry", data.message); - }); - }); - - /* - * Edit Winsync Agreement - */ - $(document).on('click', '.winsync-agmt-edit-btn', function(e) { - e.preventDefault(); - clear_winsync_agmt_wizard(); - var suffix = $("#select-repl-winsync-suffix").val(); - var data = repl_winsync_agmt_table.row( $(this).parents('tr') ).data(); - var edit_agmt_name = data[0]; - - // Get agreement from DS and populate form - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-winsync-agmt', 'get', '--suffix=' + suffix, '"' + edit_agmt_name + '"']; - log_cmd('.winsync-agmt-edit-btn (click)', 'Get replication winsync agreement', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - var agmt_obj = JSON.parse(data); - - // Set agreement form values - $("#winsync-agmt-wizard-title").html("Edit Winsync Agreement"); - // Hide init dropdown - $("#winsync-init-chbx").hide(); - $("#winsync-agmt-cn").val(edit_agmt_name); - for (var attr in agmt_obj['attrs']) { - var val = agmt_obj['attrs'][attr][0]; - attr = attr.toLowerCase(); - $("#winsync-" + attr).val(val); - if (val == "on") { - $("#winsync-" + attr + "-checkbox").prop('checked', true); - } else if (val == "off") { - $("#winsync-" + attr + "-checkbox").prop('checked', false); - } - repl_winsync_agmt_values[attr] = val; - } - - // Fill Password Confirm Input - if ( 'nsds5replicacredentials' in agmt_obj['attrs'] ){ - $("#winsync-nsds5replicacredentials-confirm").val(agmt_obj['attrs']["nsds5replicacredentials"][0]); - } - - // Transport info - val = agmt_obj['attrs']["nsds5replicatransportinfo"][0].toLowerCase(); - if (val == "ldap"){ - $("#winsync-nsds5replicatransportinfo").val("LDAP"); - } else if (val == "ldaps"){ - $("#winsync-nsds5replicatransportinfo").val("LDAPS"); - } else if (val == "starttls" || val == "tls"){ - $("#winsync-nsds5replicatransportinfo").val("StartTLS"); - } - - // Finally open the form - $("#winsync-agmt-form").modal('toggle'); - }).fail(function(data) { - popup_err("Failed to load replication winsync agreement entry", data.message); - }); - }); - - - // Handle disabling/enabling of agmt schedule panel - $('#agmt-schedule-panel *').attr('disabled', true); /// Disabled by default - $("#agmt-schedule-checkbox").change(function() { - if(this.checked) { - $('#agmt-schedule-panel *').attr('disabled', true); - $("#schedule-settings").hide(); - } else { - $('#agmt-schedule-panel *').attr('disabled', false); - $("#schedule-settings").show(); - } - }); - - // Based on the connection type change the agmt-auth options - $("#nsds5replicatransportinfo").change(function() { - var ldap_opts = {"Simple": "Simple", - "SASL/DIGEST-MD5": "SASL/DIGEST-MD5", - "SASL/GSSAPI": "SASL/GSSAPI"}; - var ldaps_opts = {"Simple": "Simple", - "SSL Client Authentication": "SSL Client Authentication", - "SASL/DIGEST-MD5": "SASL/DIGEST-MD5"}; - var $auth = $("#nsds5replicabindmethod"); - $auth.empty(); - var conn = $('#nsds5replicatransportinfo').val(); - if (conn == "LDAP"){ - $.each(ldap_opts, function(key, value) { - $auth.append($("").attr("value", value).text(key)); - }); - } else { - // TLS options - $.each(ldaps_opts, function(key, value) { - $auth.append($("").attr("value", value).text(key)); - }); - } - $("#nsds5replicabinddn").prop('disabled', false); - $("#nsds5replicacredentials").prop('disabled', false); - $("#nsds5replicacredentials-confirm").prop('disabled', false); - }); - - // Check for auth changes and disable/enable bind DN & password - $("#nsds5replicabindmethod").change(function() { - var authtype = $('#nsds5replicabindmethod').val(); - if (authtype == "SSL Client Authentication") { - $("#nsds5replicabinddn").prop('disabled', true); - $("#nsds5replicacredentials").prop('disabled', true); - $("#nsds5replicacredentials-confirm").prop('disabled', true); - } else { - $("#nsds5replicabinddn").prop('disabled', false); - $("#nsds5replicacredentials").prop('disabled', false); - $("#nsds5replicacredentials-confirm").prop('disabled', false); - } - }); - - // Create time picker for agmt schedule (start end times)) - $('input.timepicker').timepicker({ - 'timeFormat': 'H:i', - 'step': 15 - }); - - // Accordion opening/closings - - $(".ds-accordion-panel").css('display','none'); - - $("#repl-config-accordion").on("click", function() { - this.classList.toggle("active"); - var panel = this.nextElementSibling; - if (panel.style.display === "block") { - var show = "► Show Advanced Settings "; - $(this).html(show); - panel.style.display = "none"; - $(this).blur(); - } else { - var hide = "▼ Hide Advanced Settings "; - $(this).html(hide); - panel.style.display = "block"; - $(this).blur(); - } - }); - - $("#frac-accordion").on("click", function() { - this.classList.toggle("active"); - var panel = this.nextElementSibling; - if (panel.style.display === "block") { - var show = "► Show Fractional Settings "; - $(this).html(show); - panel.style.display = "none"; - $(this).blur(); - } else { - var hide = "▼ Hide Fractional Settings "; - $(this).html(hide); - panel.style.display = "block"; - $(this).blur(); - } - }); - - $("#schedule-accordion").on("click", function() { - this.classList.toggle("active"); - var panel = this.nextElementSibling; - if (panel.style.display === "block") { - var show = "► Show Schedule Settings "; - $(this).html(show); - panel.style.display = "none"; - $(this).blur(); - } else { - var hide = "▼ Hide Schedule Settings "; - $(this).html(hide); - panel.style.display = "block"; - $(this).blur(); - } - }); - - /* - * Handle the repl agmt wizard select lists - */ - - /* - * Set the "select"'s list-id in a hidden field on the select attribute form - * so we know what list to update after the selection - */ - - $(".ds-fractional-btn").on('click', function() { - // reset the list - $("#select-attr-list").prop('selectedIndex',-1); - }); - $("#frac-list-add-btn").on('click', function () { - $("#attr-form-id").val("frac-exclude-list"); - }); - $("#frac-total-list-add-btn").on('click', function () { - $("#attr-form-id").val("frac-exclude-tot-list"); - }); - $("#frac-strip-list-add-btn").on('click', function () { - $("#attr-form-id").val("frac-strip-list"); - }); - - // Handle the attribute removal from the lists - $("#frac-list-remove-btn").on("click", function () { - $("#frac-exclude-list").find('option:selected').remove(); - }); - $("#frac-total-list-remove-btn").on("click", function () { - $("#frac-exclude-tot-list").find('option:selected').remove(); - }); - $("#frac-strip-list-remove-btn").on("click", function () { - $("#frac-strip-list").find('option:selected').remove(); - }); - - // Update agmt form attribute selection lists - $("#select-attr-save").on("click", function () { - // Get the id from the hidden input filed and append the attribute to it - var list_id = $("#attr-form-id").val(); - var add_attrs = $("#select-attr-list").find('option:selected'); - if (add_attrs && add_attrs != '' && add_attrs.length > 0) { - for (var i = 0; i < add_attrs.length; i++) { - if ( $('#' + list_id + ' option[value="' + add_attrs[i].text + '"]').val() === undefined) { - $('#' + list_id).append($("').attr("value", oc_name).text(oc_name); - $("#oc-parent").append(option); - } - $("#save-oc-spinner").hide(); - popup_success("The objectClass was saved in DS"); - $("#add-edit-oc-form").modal('toggle'); - }). - fail(function(data) { - $("#save-oc-spinner").hide(); - popup_err("Error", "Failed to save the objectClass\n" + data.message); - $("#add-edit-oc-form").modal('toggle'); - }); - }); - - // Required Attributes - $("#oc-must-add-button").on("click", function () { - var add_attrs = $("#schema-list").val(); - if (add_attrs && add_attrs != '' && add_attrs.length > 0) { - for (var i = 0; i < add_attrs.length; i++) { - if ( $('#oc-required-list option[value="' + add_attrs[i] + '"]').val() === undefined) { - $('#oc-required-list').append($("').attr("value", attr_name).text(attr_name); - $("#schema-list").append(option); - } - $("#save-attr-spinner").hide(); - popup_success("The attribute was saved in DS"); - $("#add-edit-attr-form").modal('toggle'); - }). - fail(function(data) { - $("#save-attr-spinner").hide(); - popup_err("Error", "Failed to save the attribute\n" + data.message); - $("#add-edit-attr-form").modal('toggle'); - }); - }); - - function load_attr_form(element) { - clear_attr_form(); - var data = schema_at_table.row(element.parents('tr') ).data(); - var edit_attr_name = data[0]; - var edit_attr_oid = data[1]; - var edit_attr_syntax = $.parseHTML(data[2])[0].title; - var edit_attr_multivalued = data[3]; - var edit_attr_eq_mr = data[4]; - var edit_attr_order_mr = data[5]; - var edit_attr_sub_mr = data[6]; - var edit_attr_desc = data[8]; - var edit_attr_aliases = data[9]; - var edit_attr_x_origin = data[10]; - var edit_attr_usage = data[11]; - var edit_attr_no_user_mod = data[12]; - var edit_attr_parent = data[13]; - if (edit_attr_eq_mr) { - edit_attr_eq_mr = data[4]; - } - if (edit_attr_order_mr) { - edit_attr_order_mr = data[5]; - } - if (edit_attr_sub_mr) { - edit_attr_sub_mr = data[6]; - } - - $("#add-edit-attr-header").html('Edit Attribute: ' + edit_attr_name); - $("#attr-name").val(edit_attr_name); - $("#attr-name").attr('disabled', true); - $("#attr-oid").val(edit_attr_oid); - $("#attr-usage")[0].value = edit_attr_usage; - $("#attr-parent")[0].value = edit_attr_parent; - $("#attr-desc").val(edit_attr_desc); - $("#attr-x-origin").val(edit_attr_x_origin); - if (edit_attr_aliases) { - $("#attr-alias").val(edit_attr_aliases.join(" ")); - } - $("#attr-syntax").val(edit_attr_syntax); - $("#attr-multivalued").prop('checked', false); - if (edit_attr_multivalued == "yes") { - $("#attr-multivalued").prop('checked', true); - } - $("#attr-no-user-mod").prop('checked', false); - if (edit_attr_no_user_mod) { - $("#attr-no-user-mod").prop('checked', true); - } - $("#save-attr-spinner").show(); - $("#attr-eq-mr-select")[0].value = edit_attr_eq_mr; - $("#attr-order-mr-select")[0].value = edit_attr_order_mr; - $("#attr-sub-mr-select")[0].value = edit_attr_sub_mr; - $("#save-attr-spinner").hide(); - - $("#add-edit-attr-form").modal('toggle'); - } - - $(document).on('click', '.attr-view-btn', function(e) { - e.preventDefault(); - load_attr_form($(this)); - $("#save-attr-button").attr('title', 'Only user-defined attributes can be modified'); - $("#save-attr-button").attr('disabled', true); - }); - - $(document).on('click', '.attr-edit-btn', function(e) { - e.preventDefault(); - load_attr_form($(this)); - }); - - $(document).on('click', '.attr-del-btn', function(e) { - e.preventDefault(); - var data = schema_at_table.row( $(this).parents('tr') ).data(); - var del_attr_name = data[0]; - var at_row = $(this); - popup_confirm("Are you sure you want to delete attribute: " + del_attr_name + "", "Confirmation", function (yes) { - if (yes) { - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket', 'schema', 'attributetypes', 'remove', del_attr_name]; - log_cmd('.attr-del-btn (click)', 'Remove attribute', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - popup_success("Attribute was successfully removed!"); - schema_at_table.row( at_row.parents('tr') ).remove().draw( false ); - $("#schema-list option[value='" + del_attr_name + "']").remove(); - }).fail(function(data) { - popup_err("Attribute removal error", del_attr_name + " removal has failed: " + data.message); - }); - } - }); - }); - - function load_oc_form(element) { - clear_oc_form(); - var data = schema_oc_table.row(element.parents('tr') ).data(); - var edit_oc_name = data[0]; - var edit_oc_oid = data[1]; - var edit_oc_parent = data[2]; - var edit_oc_required = data[3].split(" "); - var edit_oc_allowed = data[4].split(" "); - var edit_oc_x_origin = data[6]; - var edit_oc_kind = data[7]; - var edit_oc_desc = data[8]; - if (edit_oc_parent) { - edit_oc_parent = data[2]; - } - - $("#save-oc-spinner").show(); - $("#add-edit-oc-header").html('Edit Objectclass: ' + edit_oc_name); - $("#oc-name").attr('disabled', true); - $("#oc-name").val(edit_oc_name); - $("#oc-oid").val(edit_oc_oid); - $("#oc-kind")[0].value = edit_oc_kind; - $("#oc-desc").val(edit_oc_desc); - $("#oc-x-origin").val(edit_oc_x_origin); - $("#oc-parent")[0].value = edit_oc_parent; - $.each(edit_oc_required, function (i, item) { - if (item) { - $("#oc-required-list").append($(''); - } - } - }).fail(function(data) { - if (quiet === undefined) { - popup_err("Error", "Failed to get backend suffix list\n" + data.message); - } - check_inst_alive(1); - }); -} - -function get_and_set_localpwp (quiet) { - // Now populate the table - console.log("Loading local password policies..."); - var suffix = $('#local-pwp-suffix').val(); - if (suffix == null){ - return; - } - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','localpwp', 'list', suffix ]; - log_cmd('get_and_set_localpwp', 'Get local password policies', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - var obj = JSON.parse(data); - // Empty table - pwp_table.clear().draw(); - - // Populate table - for (var idx in obj['items']) { - pwp_table.row.add([ - obj['items'][idx][0], - obj['items'][idx][1], - local_pwp_html,] - ).draw( false ); - } - console.log("Finished loading password policies."); - }).fail(function(data) { - popup_err("Error", "Failed to get password policy configuration\n" + data.message); - check_inst_alive(1); - }); -} - -function get_and_set_sasl () { - // First empty the table - console.log("Loading SASL configuration..."); - - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','sasl', 'list']; - log_cmd('get_and_set_sasl', 'Get SASL mappings', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - var obj = JSON.parse(data); - sasl_table.clear().draw(); - for (var idx in obj['items']) { - var map_cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','sasl', 'get', obj['items'][idx] ]; - log_cmd('get_and_set_sasl', 'Get SASL mapping', map_cmd); - cockpit.spawn(map_cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - var map_obj = JSON.parse(data); - - // Update html table - var sasl_priority = '100'; - if ( map_obj['attrs'].hasOwnProperty('nssaslmappriority') ){ - sasl_priority = map_obj['attrs'].nssaslmappriority - } - sasl_table.row.add( [ - map_obj['attrs'].cn, - map_obj['attrs'].nssaslmapregexstring, - map_obj['attrs'].nssaslmapbasedntemplate, - map_obj['attrs'].nssaslmapfiltertemplate, - sasl_priority, - sasl_action_html - ] ).draw( false ); - }); - } - console.log("Finished loading SASL configuration."); - }).fail(function(data) { - popup_err("Failed to SASL configuration", data.message); - check_inst_alive(1); - }); -} - -function apply_mods(mods) { - var mod = mods.pop(); - - if (!mod){ - popup_success("Successfully updated configuration"); - return; /* all done*/ - } - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','config', 'replace']; - cmd.push(mod.attr + "=" + mod.val); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).then(function() { - config_values[mod.attr] = mod.val; - // Continue with next mods (if any)) - apply_mods(mods); - }, function(ex) { - popup_err("Failed to update attribute: " + mod.attr, ex.message); - // Reset HTML for remaining values that have not been processed - $("#" + mod.attr).val(config_values[mod.attr]); - for (remaining in mods) { - $("#" + remaining.attr).val(config_values[remaining.attr]); - } - check_inst_alive(1); - return; // Stop on error - }); -} - -function save_config() { - // Loop over current config_values check for differences - var mod_list = []; - - for (var attr in config_values) { - var mod = {}; - if ( $("#" + attr).is(':checkbox')) { - // Handle check boxes - if ( $("#" + attr).is(":checked")) { - if (config_values[attr] != "on") { - mod['attr'] = attr; - mod['val'] = "on"; - mod_list.push(mod); - } - } else { - // Not checked - if (config_values[attr] != "off") { - mod['attr'] = attr; - mod['val'] = "off"; - mod_list.push(mod); - } - } - } else { - // Normal input - var val = $("#" + attr).val(); - - // But first check for rootdn-pw changes and check confirm input matches - if (attr == "nsslapd-rootpw" && val != config_values[attr]) { - // Password change, make sure passwords match - if (val != $("#nsslapd-rootpw-confirm").val()){ - popup_msg("Passwords do not match!", "The Directory Manager passwords do not match, please correct before saving again."); - return; - } - } - - if ( val && val != config_values[attr]) { - mod['attr'] = attr; - mod['val'] = val; - mod_list.push(mod); - } - } - } - - // Save access log levels - var access_log_level = 0; - $(".ds-accesslog-table").each(function() { - var val = this.id; - if (this.checked){ - val = parseInt(val.replace("accesslog-", "")); - access_log_level += val; - } - }); - mod['attr'] = "nsslapd-accesslog-level"; - mod['val'] = access_log_level; - mod_list.push(mod); - - // Save error log levels - var error_log_level = 0; - $(".ds-errorlog-table").each(function() { - var val = this.id; - if (this.checked) { - val = parseInt(val.replace("errorlog-", "")); - error_log_level += val; - } - }); - mod['attr'] = "nsslapd-errorlog-level"; - mod['val'] = error_log_level; - mod_list.push(mod); - - // Build dsconf commands to apply all the mods - if (mod_list.length) { - apply_mods(mod_list); - } else { - // No changes to save, log msg? popup_msg() - } -} - - -/* - * load the server config pages - */ -$(document).ready( function() { - - // Set an interval event to wait for all the pages to load, then load the config - var init_config = setInterval(function() { - if (server_page_loaded == 1 && security_page_loaded == 1 && db_page_loaded == 1 && - repl_page_loaded == 1 && schema_page_loaded == 1 && plugin_page_loaded == 1 && - monitor_page_loaded == 1) - { - get_insts(); - clearInterval(init_config); - } - }, 250); - - console.log("Loading Server Page..."); - - $("#main-banner").load("banner.html"); - check_for_389(); - - $("#server-tab").css( 'color', '#228bc0'); - - $("#server-content").load("servers.html", function () { - // Initialize all the tables first - sasl_table = $('#sasl-table').DataTable( { - "paging": true, - "bAutoWidth": false, - "dom": '<"pull-left"f><"pull-right"l>tip', - "lengthMenu": [ 10, 25, 50, 100], - "language": { - "emptyTable": "No SASL Mappings", - "search": "Search Mappings" - }, - "columnDefs": [ { - "targets": 5, - "orderable": false - } ] - }); - - // backup/restore table - var backup_table = $('#backup-table').DataTable( { - "paging": true, - "bAutoWidth": false, - "dom": '<"pull-left"f><"pull-right"l>tip', - "lengthMenu": [ 10, 25, 50, 100], - "language": { - "emptyTable": "No backups available for restore", - "search": "Search Backups" - }, - "columnDefs": [ { - "targets": [3, 4], - "orderable": false - } ], - "columns": [ - { "width": "120px" }, - { "width": "80px" }, - { "width": "30px" }, - { "width": "40px" }, - { "width": "30px" } - ], - }); - - // Set up local passwd policy table - pwp_table = $('#passwd-policy-table').DataTable( { - "paging": true, - "bAutoWidth": false, - "dom": '<"pull-left"f><"pull-right"l>tip', - "lengthMenu": [ 10, 25, 50, 100], - "language": { - "emptyTable": "No local policies", - "search": "Search Policies" - }, - "columnDefs": [ { - "targets": 2, - "orderable": false - } ] - }); - - // Handle changing instance here - $('#select-server').on("change", function() { - server_id = $(this).val(); - server_inst = server_id.replace("slapd-", ""); - load_config(); - }); - - $('.disk-monitoring').hide(); - $(".all-pages").hide(); - $("#server-content").show(); - $("#server-config").show(); - - // To remove text border on firefox on dropdowns) - if(navigator.userAgent.toLowerCase().indexOf('firefox') > -1) { - $("select").focus( function() { - this.style.setProperty( 'outline', 'none', 'important' ); - this.style.setProperty( 'color', 'rgba(0,0,0,0)', 'important' ); - this.style.setProperty( 'text-shadow', '0 0 0 #000', 'important' ); - }); - } - - $(".save-button").on('click', function (){ - // This is for all pages. Click Save -> it saves everything - save_all(); - }); - - // Events - $(".ds-nav-choice").on('click', function (){ - $(".ds-tab-list").css( 'color', '#777'); - var tab = $(this).attr("parent-id"); - $("#" + tab).css( 'color', '#228bc0'); - }); - - $(".ds-tab-standalone").on('click', function (){ - $(".ds-tab-list").css( 'color', '#777'); - $(this).css( 'color', '#228bc0'); - }); - - $("#server-config-btn").on("click", function() { - $(".all-pages").hide(); - $("#server-content").show(); - $("#server-config").show(); - }); - $("#server-sasl-btn").on("click", function() { - $(".all-pages").hide(); - $("#server-content").show(); - $("#server-sasl").show(); - }); - $("#server-gbl-pwp-btn").on("click", function() { - $(".all-pages").hide(); - $("#server-content").show(); - $("#global-password-policy").show(); - }); - $("#server-local-pwp-btn").on("click", function() { - $(".all-pages").hide(); - $("#server-content").show(); - $("#local-password-policy").show(); - }); - $("#server-log-access-btn").on("click", function() { - $(".all-pages").hide(); - $("#server-content").show(); - $("#server-access-log").show(); - }); - $("#server-log-audit-btn").on("click", function() { - $(".all-pages").hide(); - $("#server-content").show(); - $("#server-audit-log").show(); - }); - $("#server-log-auditfail-btn").on("click", function() { - $(".all-pages").hide(); - $("#server-content").show(); - $("#server-auditfail-log").show(); - }); - $("#server-log-errors-btn").on("click", function() { - $(".all-pages").hide(); - $("#server-content").show(); - $("#server-errors-log").show(); - }); - $("#server-tasks-btn").on("click", function() { - $(".all-pages").hide(); - $("#server-content").show(); - $("#server-tasks").show(); - }); - $("#server-tuning-btn").on("click", function() { - $(".all-pages").hide(); - $("#server-content").show(); - $("#server-tuning").show(); - }); - $("#server-ldapi-btn").on("click", function() { - $(".all-pages").hide(); - $("#server-content").show(); - $("#server-ldapi").show(); - }); - - // Disable disk monitoring input if not in use - $("#nsslapd-disk-monitoring").change(function() { - if(this.checked) { - $('.disk-monitoring').show(); - } else { - $('.disk-monitoring').hide(); - } - }); - - $('.ds-loglevel-table tr').click(function(event) { - if (event.target.type !== 'checkbox') { - $(':checkbox', this).trigger('click'); - } - }); - - $("#create-sasl-map-btn").on("click", function () { - clear_sasl_map_form(); - $("#sasl-map-name").prop("readonly", false); - }); - - $("#test-sasl-regex").change(function() { - if(this.checked) { - // Test SASL mapping - $("#sasl-test-div").show(); - } else { - $("#sasl-test-div").hide(); - } - }); - - // Test SASL Mapping Regex - $("#sasl-test-regex-btn").on('click', function () { - var result = "No match!" - var regex = $("#sasl-map-regex").val().replace(/\\\(/g, '(').replace(/\\\)/g, ')'); - var test_string = $("#sasl-test-regex-string").val(); - var sasl_regex = RegExp(regex); - if (sasl_regex.test(test_string)){ - popup_msg("Match", "The text matches the regular expression"); - } else { - popup_msg("No Match", "The text does not match the regular expression"); - } - }); - - // Edit SASL mapping - $(document).on('click', '.sasl-edit-btn', function(e) { - // Load the Edit form - e.preventDefault(); - clear_sasl_map_form(); - var data = sasl_table.row( $(this).parents('tr') ).data(); - var edit_sasl_name = data[0]; - var edit_sasl_regex = data[1]; - var edit_sasl_base = data[2]; - var edit_sasl_filter = data[3]; - var edit_sasl_priority = data[4]; - - $("#sasl-header").html("Edit SASL Mapping"); - $("#sasl-map-name").val(edit_sasl_name); - $("#sasl-map-name").prop("readonly", true); - $("#sasl-map-regex").val(edit_sasl_regex); - $("#sasl-map-base").val(edit_sasl_base); - $("#sasl-map-filter").val(edit_sasl_filter); - $("#sasl-map-priority").val(edit_sasl_priority); - $("#sasl-map-form").modal("toggle"); - }); - - // Verify SASL Mapping regex - open modal and ask for "login" to test regex mapping - $(document).on('click', '.sasl-verify-btn', function(e) { - // TODO - get this working - e.preventDefault(); - var data = sasl_table.row( $(this).parents('tr') ).data(); - var verify_sasl_name = data[0]; - }); - - // Delete SASL Mapping - $(document).on('click', '.sasl-del-btn', function(e) { - e.preventDefault(); - var data = sasl_table.row( $(this).parents('tr') ).data(); - var del_sasl_name = data[0]; - var sasl_row = $(this); // Store element for callback - popup_confirm("Are you sure you want to delete sasl mapping: " + del_sasl_name + "", "Confirmation", function (yes) { - if (yes) { - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','sasl', 'delete', del_sasl_name]; - log_cmd('.sasl-del-btn (click)', 'Delete SASL mapping', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - sasl_table.row( sasl_row.parents('tr') ).remove().draw( false ); - popup_success("Removed SASL mapping " + del_sasl_name + ""); - }).fail(function(data) { - popup_err("Failed To Delete SASL Mapping: " + del_sasl_name + "", data.message); - }); - } - }); - }); - - // Load password policy and update form based on settings - // TODO - - // Global password policy form control - $("#passwordhistory").change(function() { - if(this.checked) { - $('#passwordinhistory').attr('disabled', false); - } else { - $('#passwordinhistory').attr('disabled', true); - } - }); - if ( $("#passwordhistory").is(":checked") ) { - $('#passwordinhistory *').attr('disabled', false); - } else { - $('#passwordinhistory *').attr('disabled', true); - } - - $("#passwordexp").change(function() { - if(this.checked) { - $('#expiration-attrs *').attr('disabled', false); - } else { - $('#expiration-attrs *').attr('disabled', true); - } - }); - if ( $("#passwordexp").is(":checked") ) { - $('#expiration-attrs *').attr('disabled', false); - } else { - $('#expiration-attrs *').attr('disabled', true); - } - - $("#passwordchecksyntax").change(function() { - if(this.checked) { - $('#syntax-attrs *').attr('disabled', false); - } else { - $('#syntax-attrs *').attr('disabled', true); - } - }); - if ( $("#passwordchecksyntax").is(":checked") ) { - $('#syntax-attrs *').attr('disabled', false); - } else { - $('#syntax-attrs *').attr('disabled', true); - } - - $("#passwordlockout").change(function() { - if(this.checked) { - $('#lockout-attrs *').attr('disabled', false); - } else { - $('#lockout-attrs *').attr('disabled', true); - } - }); - if ( $("#passwordlockout").is(":checked") ) { - $('#lockout-attrs *').attr('disabled', false); - } else { - $('#lockout-attrs *').attr('disabled', true); - } - - /* - * local password policy form control - */ - $("#local-passwordhistory").change(function() { - if(this.checked) { - $('#local-passwordinhistory').attr('disabled', false); - } else { - $('#local-passwordinhistory').attr('disabled', true); - } - }); - if ( $("#local-passwordhistory").is(":checked") ) { - $('#local-passwordhistory *').attr('disabled', false); - } else { - $('#local-passwordhistorys *').attr('disabled', true); - } - - $("#local-passwordexp").change(function() { - if(this.checked) { - $('#local-expiration-attrs *').attr('disabled', false); - } else { - $('#local-expiration-attrs *').attr('disabled', true); - } - }); - if ( $("#local-passwordexp").is(":checked") ) { - $('#local-expiration-attrs *').attr('disabled', false); - } else { - $('#local-expiration-attrs *').attr('disabled', true); - } - - $("#local-passwordchecksyntax").change(function() { - if(this.checked) { - $('#local-syntax-attrs *').attr('disabled', false); - } else { - $('#local-syntax-attrs *').attr('disabled', true); - } - }); - if ( $("#local-passwordchecksyntax").is(":checked") ) { - $('#local-syntax-attrs *').attr('disabled', false); - } else { - $('#local-syntax-attrs *').attr('disabled', true); - } - - $("#local-passwordlockout").change(function() { - if(this.checked) { - $('#local-lockout-attrs *').attr('disabled', false); - } else { - $('#local-lockout-attrs *').attr('disabled', true); - } - }); - if ( $("#local-passwordlockout").is(":checked") ) { - $('local-lockout-attrs *').attr('disabled', false); - } else { - $('#local-lockout-attrs *').attr('disabled', true); - } - - /* - * Logging form control - */ - $("#nsslapd-accesslog-logging-enabled").change(function() { - if(this.checked) { - $('#accesslog-attrs *').attr('disabled', false); - } else { - $('#accesslog-attrs *').attr('disabled', true); - } - }); - - $("#nsslapd-errorlog-logging-enabled").change(function() { - if(this.checked) { - $('#errorlog-attrs *').attr('disabled', false); - } else { - $('#errorlog-attrs *').attr('disabled', true); - } - }); - - $("#nsslapd-auditlog-logging-enabled").change(function() { - if(this.checked) { - $('#auditlog-attrs *').attr('disabled', false); - } else { - $('#auditlog-attrs *').attr('disabled', true); - } - }); - - $("#nsslapd-auditfaillog-logging-enabled").change(function() { - if(this.checked) { - $('#auditfaillog-attrs *').attr('disabled', false); - } else { - $('#auditfaillog-attrs *').attr('disabled', true); - } - }); - - $("#nsslapd-ndn-cache-enabled").change(function() { - if(this.checked) { - $('#nsslapd-ndn-cache-max-size').attr('disabled', false); - } else { - $('#nsslapd-ndn-cache-max-size').attr('disabled', true); - } - }); - - // LDAPI form control - $("#nsslapd-ldapilisten").change(function() { - if(this.checked) { - $('.ldapi-attrs').show(); - if ( $("#nsslapd-ldapiautobind").is(":checked") ){ - $(".autobind-attrs").show(); - if ( $("#nsslapd-ldapimaptoentries").is(":checked") ){ - $(".autobind-entry-attrs").show(); - } else { - $(".autobind-entry-attrs").hide(); - } - } else { - $(".autobind-attrs").hide(); - $(".autobind-entry-attrs").hide(); - $("#nsslapd-ldapimaptoentries").prop("checked", false ); - } - } else { - $('.ldapi-attrs').hide(); - $(".autobind-attrs").hide(); - $(".autobind-entry-attrs").hide(); - $("#nsslapd-ldapiautobind").prop("checked", false ); - $("#nsslapd-ldapimaptoentries").prop("checked", false ); - } - }); - - $("#nsslapd-ldapiautobind").change(function() { - if (this.checked){ - $(".autobind-attrs").show(); - if ( $("#nsslapd-ldapimaptoentries").is(":checked") ){ - $(".autobind-entry-attrs").show(); - } else { - $(".autobind-entry-attrs").hide(); - } - } else { - $(".autobind-attrs").hide(); - $(".autobind-entry-attrs").hide(); - $("#nsslapd-ldapimaptoentries").prop("checked", false ); - } - }); - - $("#nsslapd-ldapimaptoentries").change(function() { - if (this.checked){ - $(".autobind-entry-attrs").show(); - } else { - $(".autobind-entry-attrs").hide(); - } - }); - - /* - * Modal Forms - */ - - /* - * Local password policy - */ - $("#create-local-pwp-btn").on("click", function () { - clear_local_pwp_form(); - }); - - $("#local-pwp-save").on("click", function() { - /* - * We are either saving a new policy or editing an existing one - * If we are editing and we remove a setting, we have to set it - * to the default value - so it makes things a little more tedious - * for editing a local policy - */ - - // Is this the create or edit form? - var edit = false; - if ( $("#local-pwp-header").text().startsWith('Edit') ) { - edit = true; - } - - /* - * Get all the current values from the form. - */ - var policy_name = $("#local-entry-dn").val(); - var pwp_track = "off"; - if ( $("#local-passwordtrackupdatetime").is(":checked") ) { - pwp_track = "on"; - } - var pwp_passwordchange = "off"; - if ($("#local-passwordchange").is(":checked") ){ - pwp_passwordchange = "on"; - } - var pwp_passwordmustchange = "off"; - if ($("#local-passwordmustchange").is(":checked") ){ - pwp_passwordmustchange = "on"; - } - var pwp_history = "off"; - if ($("#local-passwordhistory").is(":checked") ){ - pwp_history = "on"; - } - var pwp_exp = "off"; - if ($("#local-passwordexp").is(":checked") ){ - pwp_exp = "on"; - } - var pwp_sendexp = "off"; - if ($("#local-passwordsendexpiringtime").is(":checked") ){ - pwp_sendexp = "on"; - } - var pwp_lockout = "off"; - if ($("#local-passwordlockout").is(":checked") ){ - pwp_lockout = "on"; - } - var pwp_unlock = "off"; - if ($("#local-passwordunlock").is(":checked") ){ - pwp_unlock = "on"; - } - var pwp_checksyntax = "off"; - if ($("#local-passwordchecksyntax").is(":checked") ){ - pwp_checksyntax = "on"; - } - var pwp_palindrome = "on"; - if ( $("#local-passwordpalindrome").is(":checked") ){ - pwp_palindrome = "off"; - } - var pwp_dictcheck = "off"; - if ( $("#local-passworddictcheck").is(":checked") ){ - pwp_dictcheck = "on"; - } - - var pwp_admin = $("#local-passwordadmindn").val(); - var pwp_inhistory = $("#local-passwordinhistory").val(); - var pwp_minage = $("#local-passwordminage").val(); - var pwp_maxage = $("#local-passwordmaxage").val(); - var pwp_gracelimit = $("#local-passwordgracelimit").val(); - var pwp_warning = $("#local-passwordwarning").val(); - var pwp_maxfailure = $("#local-passwordmaxfailure").val(); - var pwp_failcount = $("#local-passwordresetfailurecount").val(); - var pwp_lockoutdur = $("#local-passwordlockoutduration").val(); - var pwp_minlen = $("#local-passwordminlength").val(); - var pwp_mindigits = $("#local-passwordmindigits").val(); - var pwp_minalphas = $("#local-passwordminalphas").val(); - var pwp_minuppers = $("#local-passwordminuppers").val(); - var pwp_minlowers = $("#local-passwordminlowers").val(); - var pwp_minspecials = $("#local-passwordminspecials").val(); - var pwp_min8bits = $("#local-passwordmin8bit").val(); - var pwp_maxrepeats = $("#local-passwordmaxrepeats").val(); - var pwp_mincat = $("#local-passwordmincategories").val(); - var pwp_mintoken = $("#local-passwordmintokenlength").val(); - var pwp_badwords = $("#local-passwordbadwords").val(); - var pwp_userattrs = $("#local-passworduserattributes").val(); - var pwp_maxseq = $("#local-passwordmaxsequence").val(); - var pwp_maxseqset = $("#local-passwordmaxseqsets").val(); - var pwp_maxclass = $("#local-passwordmaxclasschars").val(); - var pwp_scheme = $("#local-passwordstoragescheme").val(); - - var pwp_type = "User Policy"; - if ( $("#subtree-pwp-radio").is(":checked")) { - pwp_type = "Subtree Policy"; - } - - /* - * Go through all the settings and create an arg list, but if editing - * the policy and the value is now "", we need to set it to the default - * value. - */ - arg_list = []; - - // Do the on/off settings first - arg_list.push('--pwdtrack=' + pwp_track); - arg_list.push('--pwdchange=' + pwp_passwordchange); - arg_list.push('--pwdmustchange=' + pwp_passwordmustchange); - arg_list.push('--pwdhistory=' + pwp_history); - arg_list.push('--pwdexpire=' + pwp_exp); - arg_list.push('--pwdlockout=' + pwp_lockout); - arg_list.push('--pwdunlock=' + pwp_unlock); - arg_list.push('--pwdchecksyntax=' + pwp_checksyntax); - arg_list.push('--pwdpalindrome=' + pwp_palindrome); - arg_list.push('--pwddictcheck=' + pwp_dictcheck); - arg_list.push('--pwdsendexpiring=' + pwp_sendexp); - // Do the rest - if ( !add_validate_arg (arg_list, "num", pwp_inhistory, "0", edit, 'passwordinhistory', '--pwdhistorycount', 'Passwords in history') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_minage, "0", edit, 'passwordminage', '--pwdminage', 'Allowed Password Changes') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_maxage, "0", edit, 'passwordmaxage', '--pwdmaxage', 'Password Expiration Time') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_gracelimit, "0", edit, 'passwordgracelimit', '--pwdgracelimit', 'Allowed Logins') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_inhistory, "0", edit, 'passwordwarning', '--pwdwarning', 'Password Warning') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_maxfailure, "0", edit, 'passwordmaxfailure', '--pwdmaxfailures', 'Number of Failed Logins') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_failcount, "0", edit, 'passwordresetfailurecount', '--pwdresetfailcount', 'Failure Count Reset') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_lockoutdur, "0", edit, 'passwordlockoutduration', '--pwdlockoutduration', 'Time Until Account Unlock') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_minlen, "6", edit, 'passwordminlength', '--pwdminlen', 'Password Minimum Length') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_mindigits, "0", edit, 'passwordmindigits', '--pwdmindigits', 'Minimum Digits') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_minalphas, "0", edit, 'passwordminalphas', '--pwdminalphas', 'Minimum Alphas') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_minuppers, "0", edit, 'passwordminuppers', '--pwdminuppers', 'Minimum Uppercase Characters') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_minlowers, "0", edit, 'passwordminlowers', '--pwdminlowers', 'Minimum Lowercase Characters') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_minspecials, "0", edit, 'passwordminspecials', '--pwdminspecials', 'Minimum Special Characters') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_min8bits, "0", edit, 'passwordmin8bits', '--pwdmin8bits', 'Minimum Alphas') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_maxrepeats, "0", edit, 'passwordmaxrepeats', '--pwdmaxrepeats', 'Maximum Repeats') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_mincat, "3", edit, 'passwordmincategories', '--pwdmincatagories', 'Minimum Catagories') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_mintoken, "3", edit, 'passwordmintokenlength', '--pwdmintokenlen', 'Minimum Alphas') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_maxseq, "0", edit, 'passwordmaxsequence', '--pwdmaxseq', 'Maximum Sequence') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_maxseqset, "0", edit, 'passwordmaxseqsets', '--pwdmaxseqsets', 'Maximum Sequence Sets') ) { return; } - if ( !add_validate_arg (arg_list, "num", pwp_maxclass, "0", edit, 'passwordmaxclasschars', '--pwdmaxclasschars', 'Maximum Character Classes') ) { return; } - if ( !add_validate_arg (arg_list, "dn", pwp_admin, "", edit, 'passwordadmindn', '--pwdadmin', 'Password Administrator') ) { return; } - if (pwp_badwords != "" || (edit && localpwp_values['passwordbadwords'] !== undefined && pwp_badwords != localpwp_values['passwordbadwords'])) { - arg_list.push('--pwdbadwords=' + pwp_badwords); - } - if (pwp_userattrs != "" || (edit && localpwp_values['passworduserattributes'] !== undefined && pwp_userattrs != localpwp_values['passworduserattributes'])) { - arg_list.push('--pwduserattrs=' + pwp_userattrs); - } - if (pwp_scheme != "" || (edit && localpwp_values['passwordstoragescheme'] !== undefined && pwp_scheme != localpwp_values['passwordstoragescheme'])) { - arg_list.push('--pwdscheme=' + pwp_scheme); - } - - /* - * Update/Add Password policy to DS - */ - if ( edit ) { - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','localpwp', 'set', policy_name]; - cmd = cmd.concat(arg_list); - log_cmd('local-pwp-save', 'Set local password policy', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - popup_success('Successfully edited local password policy'); - $("#local-pwp-form").modal('toggle') - }).fail(function(data) { - popup_err("Failed to edit local password policy", data.message); - }); - } else { - // Create new local policy - var action = "addsubtree"; - if (pwp_type == "User Policy") { - action = "adduser"; - } - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','localpwp', action, policy_name]; - cmd = cmd.concat(arg_list); - log_cmd('local-pwp-save', 'Add local password policy', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - pwp_table.row.add( [ - policy_name, - pwp_type, - local_pwp_html - ] ).draw( false ); - popup_success('Successfully created local password policy'); - $("#local-pwp-form").modal('toggle'); - }).fail(function(data) { - popup_err("Failed to create local password policy", data.message); - }); - } - }); - - // Delete local password policy - $(document).on('click', '.delete-local-pwp', function(e) { - e.preventDefault(); - // Update HTML table - var data = pwp_table.row( $(this).parents('tr') ).data(); - var del_pwp_name = data[0]; - var pwp_row = $(this); - popup_confirm("Are you sure you want to delete local password policy: " + del_pwp_name + "", "Confirmation", function (yes) { - if (yes) { - // Delete pwp from DS - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','localpwp', 'remove', del_pwp_name]; - log_cmd('.delete-local-pwp (click)', 'Remove local password policy', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - // Update html table - pwp_table.row( pwp_row.parents('tr') ).remove().draw( false ); - popup_success('Successfully deleted local password policy'); - }).fail(function(data) { - popup_err("Failed to delete local password policy", data.message); - }); - } - }); - }); - - // SASL Mappings Form - $("#sasl-map-save").on("click", function() { - var sasl_map_name = $("#sasl-map-name").val(); - var sasl_regex = $("#sasl-map-regex").val(); - var sasl_base = $("#sasl-map-base").val(); - var sasl_filter = $("#sasl-map-filter").val(); - var sasl_priority = $("#sasl-map-priority").val(); - - // Validate values - if (sasl_map_name == '') { - report_err($("#sasl-map-name"), 'You must provide a mapping name'); - return; - } - if (sasl_map_name == '') { - report_err($("#sasl-map-regex"), 'You must provide an regex'); - return; - } - if (sasl_regex == '') { - report_err($("#sasl-map-base"), 'You must provide a base DN template'); - return; - } - if (sasl_filter == '') { - report_err($("#sasl-map-filter"), 'You must provide an filter template'); - return; - } - if (sasl_priority == '') { - sasl_priority = '100' - } else if (valid_num(sasl_priority)) { - var priority = Number(sasl_priority); - if (priority < 1 || priority > 100) { - report_err($("#sasl-map-priority"), 'You must provide a number between 1 and 100'); - return; - } - } else { - report_err($("#sasl-map-priority"), 'You must provide a number between 1 and 100'); - return; - } - - // Build command line args - var sasl_name_cmd = "--cn=" + sasl_map_name ; - var sasl_regex_cmd = "--nsSaslMapRegexString=" + sasl_regex; - var sasl_base_cmd = "--nsSaslMapBaseDNTemplate=" + sasl_base; - var sasl_filter_cmd = "--nsSaslMapFilterTemplate=" + sasl_filter; - var sasl_priority_cmd = "--nsSaslMapPriority=" + sasl_priority; - - if ( $("#sasl-header").html().includes("Create") ) { - // Create new mapping and update table - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','sasl', 'create', - sasl_name_cmd, sasl_regex_cmd, sasl_base_cmd, sasl_filter_cmd, sasl_priority_cmd]; - log_cmd('#sasl-map-save (click)', 'Add SASL mapping', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function() { - // Update html table - sasl_table.row.add( [ - sasl_map_name, - sasl_regex, - sasl_base, - sasl_filter, - sasl_priority, - sasl_action_html - ] ).draw( false ); - popup_success("Successfully added new SASL mapping"); - $("#sasl-map-form").modal('toggle'); - }).fail(function(data) { - popup_err("Failed To Add SASL Mapping: " + sasl_map_name, data.message); - $("#sasl-map-form").modal("toggle"); - }); - } else { - // Editing mapping. First delete the old mapping - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','sasl', 'delete', sasl_map_name]; - log_cmd('#sasl-map-save (click)', 'Delete SASL mapping', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function() { - // Remove row from old - sasl_table.rows( function ( idx, data, node ) { - return data[0] == sasl_map_name; - }).remove().draw(); - - // Then add new mapping and update table - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','sasl', 'create', - sasl_name_cmd, sasl_regex_cmd, sasl_base_cmd, sasl_filter_cmd, sasl_priority_cmd]; - log_cmd('#sasl-map-save (click)', 'Add SASL mapping', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function() { - // Update html table - sasl_table.row.add( [ - sasl_map_name, - sasl_regex, - sasl_base, - sasl_filter, - sasl_priority, - sasl_action_html - ] ).draw( false ); - popup_success("Successfully added new SASL mapping"); - $("#sasl-map-form").modal('toggle'); - }).fail(function(data) { - popup_err("Failure Adding SASL Mapping", - "Failed To Add SASL Mapping: " + sasl_map_name + ": \n" + data.message); - $("#sasl-map-form").modal("toggle"); - }); - }).fail(function(data) { - popup_err("Failure Deleting Old SASL Mapping", - "Failed To Delete SASL Mapping: " + sasl_map_name + ": \n" + data.message); - $("#sasl-map-form").modal("toggle"); - }); - } - }); - - /* - * Stop, Start, and Restart server - */ - $("#start-server-btn").on("click", function () { - $("#ds-start-inst").html(" Starting instance " + server_id + "..."); - $("#start-instance-form").modal('toggle'); - var cmd = [DSCTL, server_inst, 'start']; - log_cmd('#start-server-btn (click)', 'Start server instance', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - $("#start-instance-form").modal('toggle'); - load_config(); - popup_success("Started instance \"" + server_id + "\""); - }).fail(function(data) { - $("#start-instance-form").modal('toggle'); - popup_err("Failed to start instance \"" + server_id, data.message); - }); - }); - - $("#stop-server-btn").on("click", function () { - $("#ds-stop-inst").html(" Stopping instance " + server_id + "..."); - $("#stop-instance-form").modal('toggle'); - var cmd = [DSCTL, server_inst, 'stop']; - log_cmd('#stop-server-btn (click)', 'Stop server instance', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - $("#stop-instance-form").modal('toggle'); - popup_success("Stopped instance \"" + server_id + "\""); - check_inst_alive(); - }).fail(function(data) { - $("#stop-instance-form").modal('toggle'); - popup_err("Error", "Failed to stop instance \"" + server_id+ "\"", data.message); - check_inst_alive(); - }); - }); - - $("#restart-server-btn").on("click", function () { - $("#ds-restart-inst").html(" Retarting instance " + server_id + "..."); - $("#restart-instance-form").modal('toggle'); - var cmd = [DSCTL, server_inst, 'restart']; - log_cmd('#restart-server-btn (click)', 'Restart server instance', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - $("#restart-instance-form").modal('toggle'); - load_config(); - popup_success("Restarted instance \"" + server_id + "\""); - }).fail(function(data) { - $("#restart-instance-form").modal('toggle'); - popup_err("Failed to restart instance \"" + server_id + "\"", data.message); - }); - }); - - /* Backup server */ - $("#ds-backup-btn").on('click', function () { - var backup_name = $("#backup-name").val(); - if (backup_name == ""){ - popup_msg("Error", "Backup must have a name"); - return; - } - if (backup_name.indexOf(' ') >= 0) { - popup_msg("Error", "Backup name can not contain any spaces"); - return; - } - if (backup_name.indexOf('/') >= 0) { - popup_msg("Error", "Backup name can not contain a forward slash. " + - "Backups are written to the server's backup directory (nsslapd-bakdir)"); - return; - } - var cmd = ['status-dirsrv', server_inst]; - $("#backup-spinner").show(); - cockpit.spawn(cmd, { superuser: true}). - done(function() { - var cmd = [DSCONF, server_inst, 'backup', 'create', backup_name]; - log_cmd('#ds-backup-btn (click)', 'Backup server instance', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}). - done(function(data) { - $("#backup-spinner").hide(); - popup_success("Backup has been created"); - $("#backup-form").modal('toggle'); - }). - fail(function(data) { - $("#backup-spinner").hide(); - popup_err("Failed to backup the server", data.message); - }) - }). - fail(function() { - var cmd = [DSCTL, server_inst, 'db2bak', backup_name]; - log_cmd('#ds-backup-btn (click)', 'Backup server instance (offline)', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}). - done(function(data) { - $("#backup-spinner").hide(); - popup_success("Backup has been created"); - $("#backup-form").modal('toggle'); - }). - fail(function(data) { - $("#backup-spinner").hide(); - popup_err("Failed to backup the server", data.message); - }); - }); - }); - - $("#backup-server-btn").on('click', function () { - $("#backup-name").val(""); - }); - - /* Restore. load restore table with current backups */ - $("#restore-server-btn").on('click', function () { - var cmd = [DSCTL, server_id, '-j', 'backups']; - log_cmd('#restore-server-btn (click)', 'Restore server instance', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - var backup_btn = ""; - var del_btn = ""; - var obj = JSON.parse(data); - backup_table.clear().draw( false ); - for (var i = 0; i < obj.items.length; i++) { - var backup_name = obj.items[i][0]; - var backup_date = obj.items[i][1]; - var backup_size = obj.items[i][2]; - backup_table.row.add([backup_name, backup_date, backup_size, backup_btn, del_btn]).draw( false ); - } - }).fail(function(data) { - popup_err("Failed to get list of backups", data.message); - }); - }); - - /* Restore server */ - $(document).on('click', '.restore-btn', function(e) { - e.preventDefault(); - var data = backup_table.row( $(this).parents('tr') ).data(); - var restore_name = data[0]; - popup_confirm("Are you sure you want to restore this backup: " + restore_name + "", "Confirmation", function (yes) { - if (yes) { - var cmd = ['status-dirsrv', server_inst]; - $("#restore-spinner").show(); - cockpit.spawn(cmd, { superuser: true}). - done(function() { - var cmd = [DSCONF, server_inst, 'backup', 'restore', restore_name]; - log_cmd('.restore-btn (click)', 'Restore server instance(online)', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}). - done(function(data) { - $("#restore-spinner").hide(); - popup_success("The backup has been restored"); - $("#restore-form").modal('toggle'); - }). - fail(function(data) { - $("#restore-spinner").hide(); - popup_err("Failed to restore from the backup", data.message); - }); - }). - fail(function() { - var cmd = [DSCTL, server_inst, 'bak2db', restore_name]; - log_cmd('.restore-btn (click)', 'Restore server instance(offline)', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}). - done(function(data) { - $("#restore-spinner").hide(); - popup_success("The backup has been restored"); - $("#restore-form").modal('toggle'); - }). - fail(function(data) { - $("#restore-spinner").hide(); - popup_err("Failed to restore from the backup", data.message); - }); - }); - } - }); - }); - - /* Delete backup directory */ - $(document).on('click', '.ds-del-backup-btn', function(e) { - e.preventDefault(); - var data = backup_table.row( $(this).parents('tr') ).data(); - var restore_name = data[0]; - var backup_row = $(this); - popup_confirm("Are you sure you want to delete this backup: " + restore_name + "", "Confirmation", function (yes) { - if (yes) { - var cmd = [DSCTL, server_inst, 'backups', '--delete', restore_name]; - $("#restore-spinner").show(); - log_cmd('.ds-del-backup-btn (click)', 'Delete backup', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - $("#restore-spinner").hide(); - backup_table.row( backup_row.parents('tr') ).remove().draw( false ); - popup_success("The backup has been deleted"); - }).fail(function(data) { - $("#restore-spinner").hide(); - popup_err("Failed to delete the backup", data.message); - }); - } - }); - }); - - /* reload schema */ - $("#schema-reload-btn").on("click", function () { - var schema_dir = $("#reload-dir").val(); - if (schema_dir != ""){ - var cmd = [DSCONF, server_id, 'schema', 'reload', '--schemadir', schema_dir, '--wait']; - } else { - var cmd = [DSCONF, server_id, 'schema', 'reload', '--wait']; - } - $("#reload-spinner").show(); - log_cmd('#schema-reload-btn (click)', 'Reload schema files', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - popup_success("Successfully reloaded schema"); // TODO use timed interval success msg (waiting for another PR top be merged before we can add it) - $("#schema-reload-form").modal('toggle'); - $("#reload-spinner").hide(); - }).fail(function(data) { - popup_err("Failed to reload schema files", data.message); - $("#reload-spinner").hide(); - }); - }); - - - // Remove instance - $("#remove-server-btn").on("click", function () { - popup_confirm("Are you sure you want to this remove instance: " + server_id + "", "Confirmation", function (yes) { - if (yes) { - var cmd = [DSCTL, server_id, "remove", "--doit"]; - $("#ds-remove-inst").html(" Removing instance " + server_id + "..."); - $("#remove-instance-form").modal('toggle'); - log_cmd('#remove-server-btn (click)', 'Remove instance', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - $("#remove-instance-form").modal('toggle'); - popup_success("Instance has been deleted"); - get_insts(); - }).fail(function(data) { - $("#remove-instance-form").modal('toggle'); - popup_err("Failed to remove instance", data.message); - }); - } - }); - }); - - // Create instance form - $("#create-server-btn").on("click", function() { - clear_inst_form(); - set_ports(); - }); - $("#no-inst-create-btn").on("click", function () { - clear_inst_form(); - }); - - // Create Instance - $("#create-inst-save").on("click", function() { - $(".ds-modal-error").hide(); - $(".ds-inst-input").css("border-color", "initial"); - - /* - * Validate settings and update the INF settings - */ - var setup_inf = create_inf_template; - - // Server ID - var new_server_id = $("#create-inst-serverid").val(); - if (new_server_id == ""){ - report_err($("#create-inst-serverid"), 'You must provide an Instance name'); - return; - } else { - new_server_id = new_server_id.replace(/^slapd-/i, ""); // strip "slapd-" - setup_inf = setup_inf.replace('INST_NAME', new_server_id); - } - - // Port - var server_port = $("#create-inst-port").val(); - if (server_port == ""){ - report_err($("#create-inst-port"), 'You must provide a port number'); - return; - } else if (!valid_num(server_port)) { - report_err($("#create-inst-port"), 'Port must be a number!'); - return; - } else { - setup_inf = setup_inf.replace('PORT', server_port); - } - - // Secure Port - var secure_port = $("#create-inst-secureport").val(); - if (secure_port == ""){ - report_err($("#create-inst-secureport"), 'You must provide a secure port number'); - return; - } else if (!valid_num(secure_port)) { - report_err($("#create-inst-secureport"), 'Secure port must be a number!'); - return; - } else { - setup_inf = setup_inf.replace('SECURE_PORT', secure_port); - } - - // Root DN - var server_rootdn = $("#create-inst-rootdn").val(); - if (server_rootdn == ""){ - report_err($("#create-inst-rootdn"), 'You must provide a Directory Manager DN'); - return; - } else { - setup_inf = setup_inf.replace('ROOTDN', server_rootdn); - } - - // Setup Self-Signed Certs - if ( $("#create-inst-tls").is(":checked") ){ - setup_inf = setup_inf.replace('SELF_SIGN', 'True'); - } else { - setup_inf = setup_inf.replace('SELF_SIGN', 'False'); - } - - // Root DN password - var root_pw = $("#rootdn-pw").val(); - var root_pw_confirm = $("#rootdn-pw-confirm").val(); - if (root_pw != root_pw_confirm) { - report_err($("#rootdn-pw"), 'Directory Manager passwords do not match!'); - $("#rootdn-pw-confirm").css("border-color", "red"); - return; - } else if (root_pw == ""){ - report_err($("#rootdn-pw"), 'Directory Manager password can not be empty!'); - $("#rootdn-pw-confirm").css("border-color", "red"); - return; - } else { - setup_inf = setup_inf.replace('ROOTPW', root_pw); - } - - // Backend/Suffix - var backend_name = $("#backend-name").val(); - var backend_suffix = $("#backend-suffix").val(); - if ( (backend_name != "" && backend_suffix == "") || (backend_name == "" && backend_suffix != "") ) { - if (backend_name == ""){ - report_err($("#backend-name"), 'If you specify a backend suffix, you must also specify a backend name'); - return; - } else { - report_err($("#backend-suffix"), 'If you specify a backend name, you must also specify a backend suffix'); - return; - } - } - if (backend_name != ""){ - // We definitely have a backend name and suffix, next validate the suffix is a DN - if (valid_dn(backend_suffix)) { - // It's valid, add it - setup_inf += "\n[backend-" + backend_name + "]\nsuffix = " + backend_suffix + "\n"; - } else { - // Not a valid DN - report_err($("#backend-suffix"), 'Invalid DN for Backend Suffix'); - return; - } - if ( $("#create-sample-entries").is(":checked") ) { - setup_inf += '\nsample_entries = yes\n'; - } else { - setup_inf += '\nsample_entries = no\n'; - } - } - - /* - * Here are steps we take to create the instance - * - * [1] Get FQDN Name for nsslapd-localhost setting in setup file - * [2] Create a file for the inf setup parameters - * [3] Set strict permissions on that file - * [4] Populate the new setup file with settings (including cleartext password) - * [5] Create the instance - * [6] Remove setup file - */ - cockpit.spawn(["hostname", "--fqdn"], { superuser: true, "err": "message" }).fail(function(ex) { - // Failed to get FQDN - popup_err("Failed to get hostname!", ex.message); - }).done(function (data){ - /* - * We have FQDN, so set the hostname in inf file, and create the setup file - */ - setup_inf = setup_inf.replace('FQDN', data); - var setup_file = "/tmp/389-setup-" + (new Date).getTime() + ".inf"; - var rm_cmd = ['rm', setup_file]; - var create_file_cmd = ['touch', setup_file]; - cockpit.spawn(create_file_cmd, { superuser: true, "err": "message" }).fail(function(ex) { - // Failed to create setup file - popup_err("Failed to create installation file!", ex.message); - }).done(function (){ - /* - * We have our new setup file, now set permissions on that setup file before we add sensitive data - */ - var chmod_cmd = ['chmod', '600', setup_file]; - cockpit.spawn(chmod_cmd, { superuser: true, "err": "message" }).fail(function(ex) { - // Failed to set permissions on setup file - cockpit.spawn(rm_cmd, { superuser: true }); // Remove Inf file with clear text password - $("#create-inst-spinner").hide(); - popup_err("Failed to set permission on setup file " + setup_file + ": ", ex.message); - }).done(function (){ - /* - * Success we have our setup file and it has the correct permissions. - * Now populate the setup file... - */ - var cmd = ["/bin/sh", "-c", '/usr/bin/echo -e "' + setup_inf + '" >> ' + setup_file]; - cockpit.spawn(cmd, { superuser: true, "err": "message" }).fail(function(ex) { - // Failed to populate setup file - popup_err("Failed to populate installation file!", ex.message); - }).done(function (){ - /* - * Next, create the instance... - */ - cmd = [DSCREATE, 'fromfile', setup_file]; - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV] }).fail(function(ex) { - // Failed to create the new instance! - cockpit.spawn(rm_cmd, { superuser: true }); // Remove Inf file with clear text password - $("#create-inst-spinner").hide(); - popup_err("Failed to create instance!", ex.message); - }).done(function (){ - // Success!!! Now cleanup everything up... - cockpit.spawn(rm_cmd, { superuser: true }); // Remove Inf file with clear text password - $("#create-inst-spinner").hide(); - $("#server-list-menu").attr('disabled', false); - $("#no-instances").hide(); - get_insts(); // Refresh server list - popup_success("Successfully created instance: slapd-" + new_server_id + ""); - $("#create-inst-form").modal('toggle'); - }); - }); - $("#create-inst-spinner").show(); - }); - }); - }).fail(function(data) { - console.log("failed: " + data.message); - }); - }); - - // Accordion opening/closings - $(".ds-accordion-panel").css('display','none'); - - $("#config-accordion").on("click", function() { - this.classList.toggle("active"); - var panel = this.nextElementSibling; - if (panel.style.display === "block") { - var show = "► Show Advanced Settings "; - $(this).html(show); - panel.style.display = "none"; - $(this).blur(); - } else { - var hide = "▼ Hide Advanced Settings "; - $(this).html(hide); - panel.style.display = "block"; - $(this).blur(); - } - }); - - $("#tuning-config-accordion").on("click", function() { - this.classList.toggle("active"); - var panel = this.nextElementSibling; - if (panel.style.display === "block") { - var show = "► Show Advanced Settings "; - $(this).html(show); - panel.style.display = "none"; - $(this).blur(); - } else { - var hide = "▼ Hide Advanced Settings "; - $(this).html(hide); - panel.style.display = "block"; - $(this).blur(); - } - }); - - $('#local-pwp-suffix').on('change', function () { - // Reload the table for the new selected suffix - get_and_set_localpwp(); - }); - - // Edit Local Password Policy - $(document).on('click', '.edit-local-pwp', function(e) { - e.preventDefault(); - clear_local_pwp_form(); - - var data = pwp_table.row( $(this).parents('tr') ).data(); - var policy_name = data[0]; - - // lookup the entry, and get the current settings - var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','localpwp', 'get', policy_name]; - log_cmd('.edit-local-pwp (click)', 'Get local password policy', cmd); - cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { - localpwp_values = {}; // Clear it out - var obj = JSON.parse(data); - for (var attr in obj['attrs']) { - var val = obj['attrs'][attr]; - $("#local-" + attr).val(val); - if (val == "on") { - $("#local-" + attr).prop('checked', true); - $("#local" + attr).trigger('change'); - } else if (val == "off") { - $("#local" + attr).prop('checked', false); - $("#local" + attr).trigger('change'); - } - localpwp_values[attr] = val; - } - if ( obj['pwp_type'] == "User") { - $("#user-pwp-radio").prop("checked", true ); - } else { - $("#subtree-pwp-radio").prop("checked", true ); - } - - // Set the form header and fields - $("#local-pwp-header").html("Edit Local Password Policy"); - $("#local-entry-dn").val(policy_name); - // Disable radio buttons - $("#subtree-pwp-radio").attr('disabled', true); - $("#user-pwp-radio").attr('disabled', true); - $("#local-entry-dn").attr('disabled', true); - - // Open form - $("#local-pwp-form").modal('toggle'); - - }).fail(function(data) { - popup_err("Failed to get local password policy", data.message); - }); - }); - - // Mark this page as loaded - server_page_loaded = 1; - }); // servers.html loaded -}); // Document ready diff --git a/src/cockpit/389-console/manifest.json b/src/cockpit/389-console/manifest.json deleted file mode 100644 index 80e06bd..0000000 --- a/src/cockpit/389-console/manifest.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "version": "1.0", - "name": "389-console", - "require": { - "cockpit": "120" - }, - "tools": { - "389-console": { - "label": "389 Directory Server", - "path": "index.html" - } - } -} diff --git a/src/cockpit/389-console/monitor.html b/src/cockpit/389-console/monitor.html deleted file mode 100644 index 3feaf0b..0000000 --- a/src/cockpit/389-console/monitor.html +++ /dev/null @@ -1,918 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/cockpit/389-console/node_modules.mk b/src/cockpit/389-console/node_modules.mk new file mode 100644 index 0000000..4e8e77b --- /dev/null +++ b/src/cockpit/389-console/node_modules.mk @@ -0,0 +1,9 @@ +install: package.json + test -f node_modules/webpack || npm install + +build-cockpit-plugin: webpack.config.js + npm run build; cp -r dist cockpit_dist + +clean: + rm -rf ./dist/ ./cockpit_dist/ + diff --git a/src/cockpit/389-console/org.cockpit-project.389-console.metainfo.xml b/src/cockpit/389-console/org.cockpit-project.389-console.metainfo.xml new file mode 100644 index 0000000..0432d39 --- /dev/null +++ b/src/cockpit/389-console/org.cockpit-project.389-console.metainfo.xml @@ -0,0 +1,15 @@ + + org.cockpit-project.389-console + CC0-1.0 + 389 Directory Server + + 389 Directory Server Management + + +

+ 389 Directory Server Management +

+
+ cockpit.desktop + cockpit-389-console +
diff --git a/src/cockpit/389-console/package.json b/src/cockpit/389-console/package.json new file mode 100644 index 0000000..b1ea2da --- /dev/null +++ b/src/cockpit/389-console/package.json @@ -0,0 +1,50 @@ +{ + "version": "1.0.0", + "name": "389-console", + "description": "Cockpit plugin for managing 389 Directory Server", + "author": "", + "license": "GPL-3.0-or-later", + "main": "index.js", + "scripts": { + "build": "webpack", + "eslint": "eslint --ext .jsx --ext .es6 src/", + "eslint:fix": "eslint --fix --ext .jsx --ext .es6 src/" + }, + "devDependencies": { + "@babel/core": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "@babel/preset-react": "^7.0.0", + "babel-eslint": "^9.0.0", + "babel-loader": "^8.0.0", + "chrome-remote-interface": "^0.25.5", + "compression-webpack-plugin": "^1.1.11", + "copy-webpack-plugin": "^4.5.2", + "css-loader": "^0.28.11", + "eslint": "^5.4.0", + "eslint-config-standard": "^11.0.0", + "eslint-config-standard-react": "^6.0.0", + "eslint-loader": "^2.1.0", + "eslint-plugin-flowtype": "^2.50.0", + "eslint-plugin-import": "^2.14.0", + "eslint-plugin-node": "^7.0.1", + "eslint-plugin-promise": "^4.0.0", + "eslint-plugin-react": "^7.6.1", + "eslint-plugin-standard": "^3.1.0", + "extract-text-webpack-plugin": "^4.0.0-beta.0", + "htmlparser": "^1.7.7", + "jed": "^1.1.1", + "ajv": "^6.0.0", + "sass-loader": "^7.0.3", + "sizzle": "^2.3.3", + "stdio": "^0.2.7", + "webpack": "^4.17.1", + "webpack-cli": "^3.1.0" + }, + "dependencies": { + "@babel/polyfill": "^7.0.0", + "@patternfly/react-core": "^1.29.0", + "node-sass": "^4.9.0", + "react": "^16.4.2", + "react-dom": "^16.4.2" + } +} diff --git a/src/cockpit/389-console/plugins.html b/src/cockpit/389-console/plugins.html deleted file mode 100644 index 9c24b6b..0000000 --- a/src/cockpit/389-console/plugins.html +++ /dev/null @@ -1,258 +0,0 @@ -
-

Server Plugins

- - - - - - - - - - - - - - - - - - - - - - - -
Plugin NamePlugin TypeEnabled
MemberOf Pluginbetxnpostoperationon
Replication Pluginbetxnpostoperationon
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/cockpit/389-console/replication.html b/src/cockpit/389-console/replication.html deleted file mode 100644 index d42aefe..0000000 --- a/src/cockpit/389-console/replication.html +++ /dev/null @@ -1,739 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/cockpit/389-console/rhds-banner.html b/src/cockpit/389-console/rhds-banner.html deleted file mode 100644 index fef8826..0000000 --- a/src/cockpit/389-console/rhds-banner.html +++ /dev/null @@ -1,16 +0,0 @@ -Red Hat Directory Server Management \ No newline at end of file diff --git a/src/cockpit/389-console/schema.html b/src/cockpit/389-console/schema.html deleted file mode 100644 index 74388e2..0000000 --- a/src/cockpit/389-console/schema.html +++ /dev/null @@ -1,256 +0,0 @@ - -
- - - - - - - - - - - - - - -
diff --git a/src/cockpit/389-console/security.html b/src/cockpit/389-console/security.html deleted file mode 100644 index 1444418..0000000 --- a/src/cockpit/389-console/security.html +++ /dev/null @@ -1,502 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/cockpit/389-console/servers.html b/src/cockpit/389-console/servers.html deleted file mode 100644 index 5dcb4f2..0000000 --- a/src/cockpit/389-console/servers.html +++ /dev/null @@ -1,1280 +0,0 @@ - -
- - -
-

Server Configuration Settings

-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
-
- -
-
- -
-
- -
-
- -
-
-
- - -
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
-
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
- -
-
-
- -
-
- -
- -
-
-
-
- -
-
- -
-
- -
-
- -
-
-
-
-

- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/cockpit/389-console/src/backend.html b/src/cockpit/389-console/src/backend.html new file mode 100644 index 0000000..c209f96 --- /dev/null +++ b/src/cockpit/389-console/src/backend.html @@ -0,0 +1,1007 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ diff --git a/src/cockpit/389-console/src/backend.js b/src/cockpit/389-console/src/backend.js new file mode 100644 index 0000000..e1a006e --- /dev/null +++ b/src/cockpit/389-console/src/backend.js @@ -0,0 +1,931 @@ +var prev_tree_node = null; +var ref_del_html = ""; +var attr_encrypt_del_html = ""; +var index_btn_html = + ''; + +function customMenu (node) { + var dblink_items = { + "delete_link": { + "label": "Delete DB Link", + "icon": "glyphicon glyphicon-trash", + "action": function (data) { + popup_confirm("Are you sure you want to delete this Database Link?", "Confirmation", function (yes) { + if (yes) { + + // TODO Delete db link + } + }); + } + } + }; + + var suffix_items = { + 'import': { + "label": "Initialize Suffix", + "icon": "glyphicon glyphicon-circle-arrow-right", + "action": function (data) { + var suffix_id = $(node).attr('id'); + var parent_suffix = suffix_id.substring(suffix_id.indexOf('-')+1); + $("#root-suffix-import").val(parent_suffix); + $("#import-ldif-file").val(""); + $("#import-ldif-form").modal('toggle'); + } + }, + 'export': { + "label": "Export Suffix", + "icon": "glyphicon glyphicon-circle-arrow-left", + "action": function (data) { + var suffix_id = $(node).attr('id'); + var parent_suffix = suffix_id.substring(suffix_id.indexOf('-')+1); + $("#root-suffix-export").val(parent_suffix); + $("#export-ldif-file").val(""); + $("#export-ldif-form").modal('toggle'); + } + }, + 'reindex': { + "label": "Reindex Suffix", + "icon": "glyphicon glyphicon-wrench", + "action": function (data) { + popup_confirm("This will impact DB performance during the indexing. Are you sure you want to reindex all attributes?", "Confirmation", function (yes) { + if (yes) { + // TODO Reindex suffix + } + }); + } + }, + "create_db_link": { + "label": "Create Database Link", + "icon": "glyphicon glyphicon-link", + "action": function (data) { + var suffix_id = $(node).attr('id'); + var parent_suffix = suffix_id.substring(suffix_id.indexOf('-')+1); + //clear_chaining_form(); //TODO + $("#create-db-link-form").modal('toggle'); + } + }, + "create_sub_suffix": { + "label": "Create Sub-Suffix", + "icon": "glyphicon glyphicon-triangle-bottom", + "action": function (data) { + var suffix_id = $(node).attr('id'); + var parent_suffix = suffix_id.substring(suffix_id.indexOf('-')+1); + $("#parent-suffix").html('Parent Suffix:  ' + parent_suffix); + $("#add-subsuffix-dn").val(' ,' + parent_suffix); + $("#add-subsuffix-form").modal('toggle'); + } + }, + 'delete_suffix': { + "label": "Delete Suffix", + "icon": "glyphicon glyphicon-remove", + "action": function (data) { + popup_confirm("Are you sure you want to delete suffix?", "Confirmation", function (yes) { + if (yes) { + // TODO + } + }); + } + } + }; + + if ( $(node).attr('id').startsWith('suffix') ){ + return suffix_items; + } else { + // chaining + return dblink_items; + } +}; + +function get_encoded_ref () { + var ref_encoded = $("#ref-protocol").val() + $("#ref-hostname").val(); + var ref_port = $("#ref-port").val(); + var ref_suffix = $("#ref-suffix").val(); + var ref_attrs = $("#ref-attrs").val(); + var ref_filter = $("#ref-filter").val(); + var ref_scope = $("#ref-scope").val(); + + $("#preview-ref-btn").blur(); + + if (ref_port != ""){ + ref_encoded += ":" + ref_port; + } + + if (ref_suffix == "" && (ref_attrs != "" || ref_filter != "" || ref_scope != "")) { + popup_msg("Attention!", "Missing suffix - you can not set the attributes, scope, or filter without a suffix."); + return; + } + if (ref_suffix != "" || ref_attrs != "" || ref_filter != "" || ref_scope != "") { + ref_encoded += "/" + encodeURIComponent(ref_suffix); + if ( ref_attrs != "" ) { + ref_encoded += "?" + encodeURIComponent(ref_attrs); + } else if ( ref_filter != "" || ref_scope != "" ) { + ref_encoded += "?"; + } + if ( ref_scope != "" ) { + ref_encoded += "?" + encodeURIComponent(ref_scope); + } else if ( ref_filter != "" ) { + ref_encoded += "?"; + } + if ( ref_filter != "") { + ref_encoded += "?" + encodeURIComponent(ref_filter); + } + } + return ref_encoded; +} + +function load_jstree() { + $('#db-tree').jstree({ + "plugins": [ "contextmenu", "wholerow", "sort" ], + "contextmenu": { + "items" : customMenu + }, + "core": { + "check_callback": true + } + }); + + $('#db-tree').jstree('select_node', 'ul > li:first'); + + + $('#db-tree').on("changed.jstree", function (e, data) { + var node_type = data.selected[0]; + var suffix = data.instance.get_node(data.selected[0]).text.replace(/(\r\n|\n|\r)/gm,""); + + if (node_type.startsWith("dblink")) { + var parent_suffix = node_type.substring(node_type.indexOf('-')+1); + $(".all-pages").hide(); + $("#database-content").show(); + $("#db-page").show(); + $("#chaining-header").html("Database Chaining Configuration (" + parent_suffix + ")"); + $("#chaining-page").show(); + } else { + // suffix + $(".all-pages").hide(); + $("#database-content").show(); + $("#db-page").show(); + $("#suffix-header").html("Suffix Configuration (" + suffix + ")"); + $("#suffix-page").show(); + } + }); +}; + +function clear_ref_form () { + $("#ref-scope").prop('selectedIndex',0); + $("#ref-protocol").prop('selectedIndex',0); + $("#ref-suffix").val(""); + $("#ref-filter").val(""); + $("#ref-hostname").val(""); + $("#ref-port").val(""); + $("#ref-attrs").val(""); + $("#ref-preview-field").val(""); +} + +function clear_index_form () { + $("#index-list-select").prop('selectedIndex',0); + $("#add-index-type-eq").prop('checked', false); + $("#add-index-type-pres").prop('checked', false); + $("#add-index-type-sub").prop('checked', false); + $("#add-index-type-approx").prop('checked', false); + $("#add-index-matchingrules").val(""); +} + +function clear_attr_encrypt_form() { + $("#attr-encrypt-list").prop('selectedIndex',0); + $("#nsencryptionalgorithm").prop('selectedIndex',0); +} + +$(document).ready( function() { + $("#database-content").load("backend.html", function () { + load_jstree(); + + $(".ds-suffix-panel").toggle("active"); + $(".ds-suffix-panel").css('display','none'); + + $("#create-ref-btn").on("click", function () { + clear_ref_form(); + }); + + $("#db-chaining-btn").on("click", function() { + $(".all-pages").hide(); + $("#database-content").show(); + $("#db-chaining-settings-page").show(); + }); + $("#db-global-btn").on("click", function() { + $(".all-pages").hide(); + $("#database-content").show(); + $("#db-global-page").show(); + }); + $("#db-suffix-btn").on("click", function() { + $(".all-pages").hide(); + $("#database-content").show(); + $("#db-page").show(); + $("#suffix-page").show(); + }); + + $("#chaining-adv-accordion").on("click", function() { + this.classList.toggle("active"); + var panel = this.nextElementSibling; + if (panel.style.display === "block") { + var show = "► Show Advanced Database Link Settings "; + $(this).html(show); + panel.style.display = "none"; + $(this).blur(); + } else { + var hide = "▼ Hide Advanced Database Link Settings"; + $(this).html(hide); + panel.style.display = "block"; + $(this).blur(); + } + }); + + + $("#db-system-index-accordion").on("click", function() { + this.classList.toggle("active"); + var panel = this.nextElementSibling; + if (panel.style.display === "block") { + var show = "► Show System Indexes "; + $(this).html(show); + panel.style.display = "none"; + $(this).blur(); + } else { + var hide = "▼ Hide System Indexes "; + $(this).html(hide); + panel.style.display = "block"; + $(this).blur(); + } + }); + + $("#db-index-accordion").on("click", function() { + this.classList.toggle("active"); + var panel = this.nextElementSibling; + if (panel.style.display === "block") { + var show = "► Show Database Indexes "; + $(this).html(show); + panel.style.display = "none"; + $(this).blur(); + } else { + var hide = "▼ Hide Database Indexes "; + $(this).html(hide); + panel.style.display = "block"; + $(this).blur(); + } + }); + + $("#suffix-attrencrypt-accordion").on("click", function() { + this.classList.toggle("active"); + var panel = this.nextElementSibling; + if (panel.style.display === "block") { + var show = "► Show Encrypted Attributes "; + $(this).html(show); + panel.style.display = "none"; + $(this).blur(); + } else { + var hide = "▼ Hide Encrypted Attributes "; + $(this).html(hide); + panel.style.display = "block"; + $(this).blur(); + } + }); + + + /* + We need logic to see if autocaching (import and db) is being used, and disable fields, + and set radio buttons, et + */ + + var ref_table = $('#referral-table').DataTable( { + "paging": false, + "searching": false, + "bInfo" : false, + "bAutoWidth": false, + "dom": '<"pull-left"f><"pull-right"l>tip', + "language": { + "emptyTable": "No Referrals" + }, + "columnDefs": [ + { + "targets": 1, + "orderable": false, + }, + { + "targets": 1, + "className": "ds-center" + } + ] + }); + + + $('#system-index-table').DataTable( { + "paging": true, + "bAutoWidth": false, + "dom": '<"pull-left"f><"pull-right"l>tip', + "lengthMenu": [ 10, 25, 50, 100], + "language": { + "search": "Search", + "emptyTable": "No System Indexes" + }, + "columns": [ + { "width": "10%" }, + { "width": "20px" }, + { "width": "20px" }, + { "width": "20px" }, + { "width": "20px" }, + { "width": "20%" } + ], + }); + var index_table = $('#index-table').DataTable( { + "paging": true, + "bAutoWidth": false, + "dom": '<"pull-left"f><"pull-right"l>tip', + "lengthMenu": [ 10, 25, 50, 100], + "language": { + "search": "Search", + "emptyTable": "No Indexes" + }, + "columns": [ + { "width": "10%" }, + { "width": "15px" }, + { "width": "15px" }, + { "width": "15px" }, + { "width": "15px" }, + { "width": "20%" }, + { "width": "76px" } + ], + "columnDefs": [ { + "targets": 6, + "orderable": false + } ] + }); + + + + + var attr_encrypt_table = $('#attr-encrypt-table').DataTable( { + "paging": true, + "bAutoWidth": false, + "searching": true, + "dom": '<"pull-left"f><"pull-right"l>tip', + "lengthMenu": [ 10, 25, 50, 100], + "language": { + "search": "Search", + "emptyTable": "No Encrypted Attributes" + }, + "columnDefs": [ { + "targets": 2, + "orderable": false + } ] + }); + + // Accordion opening/closings + $(".ds-accordion-panel").css('display','none'); + + var suffix_acc = document.getElementsByClassName("suffix-accordion"); + for (var i = 0; i < suffix_acc.length; i++) { + suffix_acc[i].onclick = function() { + this.classList.toggle("active"); + var panel = this.nextElementSibling; + if (panel.style.display === "block") { + panel.style.display = "none"; + } else { + panel.style.display = "block"; + } + } + } + + $("#db-accordion").on("click", function() { + this.classList.toggle("active"); + var panel = this.nextElementSibling; + if (panel.style.display === "block") { + var show = "► Show Advanced Settings"; + $(this).html(show); + panel.style.display = "none"; + $(this).blur(); + } else { + var hide = "▼ Hide Advanced Settings "; + $(this).html(hide); + panel.style.display = "block"; + $(this).blur(); + } + }); + + var db_acc = document.getElementsByClassName("db-accordion"); + for (var i = 0; i < db_acc.length; i++) { + db_acc[i].onclick = function() { + this.classList.toggle("active"); + var panel = this.nextElementSibling; + if (panel.style.display === "block") { + panel.style.display = "none"; + } else { + panel.style.display = "block"; + } + } + } + + var cache_acc = document.getElementsByClassName("cache-accordion"); + for (var i = 0; i < cache_acc.length; i++) { + cache_acc[i].onclick = function() { + this.classList.toggle("active"); + var panel = this.nextElementSibling; + if (panel.style.display === "block") { + panel.style.display = "none"; + } else { + panel.style.display = "block"; + } + } + } + + + $(".index-type").attr('readonly', true); + + if ( $("#manual-cache").is(":checked") ){ + $("#auto-cache-form").hide(); + $("#manual-cache-form").show(); + $("#nsslapd-dncachememsize").prop('disabled', false); + $("#nsslapd-dncachememsize").val(''); + $("#nsslapd-cachememsize").prop('disabled', false); + $("#nsslapd-cachememsize").val(''); + $("#nsslapd-cachesize").prop('disabled', false); + $("#nsslapd-cachesize").val(''); + } else { + $("#manual-cache-form").hide(); + $("#auto-cache-form").show(); + $("#nsslapd-dncachememsize").prop('disabled', true); + $("#nsslapd-dncachememsize").val('AUTOTUNED'); + $("#nsslapd-cachememsize").prop('disabled', true); + $("#nsslapd-cachememsize").val('AUTOTUNED'); + $("#nsslapd-cachesize").prop('disabled', true); + $("#nsslapd-cachesize").val('AUTOTUNED'); + } + + if ( $("#manual-import-cache").is(":checked") ){ + $("#auto-import-cache-form").hide(); + $("#manual-import-cache-form").show(); + } else { + $("#manual-import-cache-form").hide(); + $("#auto-import-cache-form").show(); + } + + $(".cache-role").on("change", function() { + var cache_role = $("input[name=cache-role]:checked").val(); + if (cache_role == "manual-cache") { + $("#auto-cache-form").hide(); + $("#manual-cache-form").show(); + } else { + // auto cache + $("#manual-cache-form").hide(); + $("#auto-cache-form").show(); + } + }); + + $(document).on('click', '.del-ref-btn', function(e) { + e.preventDefault(); + var data = ref_table.row( $(this).parents('tr') ).data(); + var del_ref_name = data[0]; + var ref_row = $(this); // Store element for callback + popup_confirm("Are you sure you want to delete referral: " + del_ref_name + "", "Confirmation", function (yes) { + if (yes) { + // TODO Delete mapping from DS + + // Update html table + ref_table.row( ref_row.parents('tr') ).remove().draw( false ); + } + }); + }); + + $("#backend-config-save-btn").on("click", function () { + var role = $("input[name=cache-role]:checked").val(); + if (role == "manual-cache") { + // TODO - need to get cache values and fields (overwrite AUTOTUNED) + $("#nsslapd-dncachememsize").prop('disabled', false); + $("#nsslapd-dncachememsize").val('') + $("#nsslapd-cachememsize").prop('disabled', false); + $("#nsslapd-cachememsize").val(''); + $("#nsslapd-cachesize").prop('disabled', false); + $("#nsslapd-cachesize").val(''); + } else { + // auto cache + $("#nsslapd-dncachememsize").prop('disabled', true); + $("#nsslapd-dncachememsize").val('AUTOTUNED'); + $("#nsslapd-cachememsize").prop('disabled', true); + $("#nsslapd-cachememsize").val('AUTOTUNED'); + $("#nsslapd-cachesize").prop('disabled', true); + $("#nsslapd-cachesize").val('AUTOTUNED'); + } + }); + + $(".import-cache-role").on("change", function() { + var role = $("input[name=import-cache-role]:checked").val(); + if (role == "manual-import-cache") { + $("#auto-import-cache-form").hide(); + $("#manual-import-cache-form").show(); + } else { + // auto cache + $("#manual-import-cache-form").hide(); + $("#auto-import-cache-form").show(); + } + }); + + // Based on the db-link connection type change the agmt-auth options + $("#dblink-conn").change(function() { + var ldap_opts = {"Simple": "Simple", + "SASL/DIGEST-MD5": "SASL/DIGEST-MD5", + "SASL/GSSAPI": "SASL/GSSAPI"}; + var ldaps_opts = {"Simple": "Simple", + "SSL Client Authentication": "SSL Client Authentication", + "SASL/DIGEST-MD5": "SASL/DIGEST-MD5"}; + var $auth = $("#nsbindmechanism"); + $auth.empty(); + var conn = $('#dblink-conn').val(); + if (conn == "LDAP"){ + $.each(ldap_opts, function(key, value) { + $auth.append($("").attr("value", value).text(key)); + }); + } else { + // TLS options + $.each(ldaps_opts, function(key, value) { + $auth.append($("").attr("value", value).text(key)); + }); + } + $("#nsmultiplexorbinddn").prop('disabled', false); + $("#nsmultiplexorcredentials").prop('disabled', false); + $("#nsmultiplexorcredentials-confirm").prop('disabled', false); + }); + + // Check for auth changes and disable/enable bind DN & password for db-links + $("#nsbindmechanism").change(function() { + var authtype = $('#nsbindmechanism').val(); + if (authtype == "SSL Client Authentication") { + $("#nsmultiplexorbinddn").prop('disabled', true); + $("#nsmultiplexorcredentials").prop('disabled', true); + $("#nsmultiplexorcredentials-confirm").prop('disabled', true); + } else { + $("#nsmultiplexorbinddn").prop('disabled', false); + $("#nsmultiplexorcredentials").prop('disabled', false); + $("#nsmultiplexorcredentials-confirm").prop('disabled', false); + } + }); + + // + // Modal Forms + // + + // Chaining OIDS + $("#chaining-oid-button").on("click", function() { + $(this).blur(); + }); + $("#chaining-oid-save").on("click", function() { + // Update oids + var chaining_oids = $("#avail-chaining-oid-list").val(); + for (var i = 0; chaining_oids && i < chaining_oids.length; i++) { + $('#chaining-oid-list').append($(''); + $("#select-server").prop('selectedIndex',0); + + server_id = ""; + server_inst = ""; + + $("#server-list-menu").attr('disabled', true); + $("#ds-navigation").hide(); + $(".all-pages").hide(); + $("#no-instances").show(); +} + +function check_for_389 () { + var cmd = ["rpm", "-q", "389-ds-base"]; + + cockpit.spawn(cmd, { superuser: true }).fail(function(data) { + $("#server-list-menu").attr('disabled', true); + $("#ds-navigation").hide(); + $(".all-pages").hide(); + $("#no-package").show(); + }); +} + +function check_inst_alive (connect_err) { + // Check if this instance is started, if not hide configuration pages + if (connect_err === undefined) { + connect_err = 0; + } + cmd = ['status-dirsrv', server_inst]; + cockpit.spawn(cmd, { superuser: true }).done(function () { + if (connect_err) { + $("#ds-navigation").hide(); + $(".all-pages").hide(); + $("#no-connect").show(); + } else { + // if nav page was hidden reset everything + if ($("#ds-navigation").is(":hidden") ){ + $(".all-pages").hide(); + $("#ds-navigation").show(); + $("#server-content").show(); + $("#server-config").show(); + } + $("#not-running").hide(); + $("#no-connect").hide(); + } + }).fail(function(data) { + $("#loading-page").hide(); + $("#ds-navigation").hide(); + $(".all-pages").hide(); + $("#not-running").show(); + }); +} + +function get_insts() { + // Load initial forms + $("#server-list-menu").attr('disabled', false); + $("#ds-navigation").show(); + $(".all-pages").hide(); + $("#no-instances").hide(); + + var insts = []; + var cmd = ["/bin/sh", "-c", "/usr/bin/ls -d " + DS_HOME + "slapd-*"]; + cockpit.spawn(cmd, { superuser: true }).done(function(data) { + // Parse the output, and skip removed instances and empty lines + var lines = data.split('\n'); + var i = 0; + for (i = 0; i < lines.length; i++) { + if (lines[i].endsWith(".removed") == false && lines[i] != "") { + var serverid = lines[i].replace(DS_HOME, ""); + insts.push(serverid); + } + } + + if (server_id != "None") { + $("#ds-banner").html("Managing Instance "); + } + + // Populate the server instance drop down + $("#select-server").empty(); + for (i = 0; i < insts.length; i++) { + $("#select-server").append(''); + } + $("#select-server").prop('selectedIndex',0); + + if (insts[0] === undefined) { + set_no_insts(); + $("#loading-page").hide(); + $("#everything").show(); + } else { + // We have at least one instance, make sure we "open" the UI + server_id = insts[0]; + server_inst = insts[0].replace("slapd-", ""); + check_inst_alive(); + load_config(); + } + }).fail(function(error){ + set_no_insts(); + $("#loading-page").hide(); + $("#everything").show(); + }); +} + +function report_err( input, msg) { + $(".ds-modal-error").html('Error: ' + msg); + input.css("border-color", "red"); + $(".ds-modal-error").show(); +} + + +function popup_err(title, msg) { + // Display errors from the cli (we have to use pre tags) + bootpopup({ + title: title, + content: [ + '
' + msg + '
' + ] + }); + check_inst_alive(0); +} + +function popup_msg(title, msg) { + bootpopup({ + title: title, + content: [ + '

' + msg + '

' + ] + }); +} + +function popup_confirm(msg, title, callback) { + if(typeof callback !== "function") { + callback = function() {}; + } + var answer = false; + return bootpopup({ + title: title, + content: [ + msg + ], + showclose: false, + buttons: ["no", "yes"], + yes: function() { answer = true; }, + dismiss: function() { callback(answer); }, + }); +} + +function popup_success(msg) { + $('#success-msg').html(msg); + $('#success-form').modal('show'); + setTimeout(function() {$('#success-form').modal('hide');}, 2000); +} + +// This is called when any Save button is clicked on the main page. We call +// all the save functions for all the pages here. This is not used for modal forms +function save_all () { + save_config(); // Server Config Page + // + // TODO: + // save_chaining(); + // save_chaining_suffix(); + // save_global_backend(); + // save_suffix(); + // save_security(); +} + +function load_config (){ + // Load the configuration for all the pages. + var dropdowns = ['local-pwp-suffix', 'select_repl_suffix', 'select-repl-cfg-suffix', + 'select-repl-agmt-suffix', 'select-repl-winsync-suffix', + 'cleanallruv-suffix', 'monitor-repl-backend-list']; + + // Show the spinner, and reset the pages + $("#loading-msg").html("Loading Directory Server configuration for " + server_id + "..."); + $("#everything").hide(); + $(".all-pages").hide(); + $("#loading-page").show(); + config_loaded = 0; + + /* + * Start with the dropdowns, if this fails we stop here, otherwise we assume + * we are up and running and we can load the other config/ + */ + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','backend', 'list', '--suffix']; + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + // Update dropdowns + for (var idx in dropdowns) { + $("#" + dropdowns[idx]).empty(); + } + var obj = JSON.parse(data); + for (var idx in obj['items']) { + for (var list in dropdowns){ + $("#" + dropdowns[list]).append(''); + } + } + + // Server page + get_and_set_config(); + get_and_set_sasl(); + get_and_set_localpwp(); + + // Schema page + get_and_set_schema_tables(); + + // Replication page + get_and_set_repl_config(); + get_and_set_repl_agmts(); + get_and_set_repl_winsync_agmts(); + get_and_set_cleanallruv(); + + // Security page + // Database page + // Plugin page + // Monitoring page + + // Initialize the tabs + $(".ds-tab-list").css( 'color', '#777'); + $("#server-tab").css( 'color', '#228bc0'); + + // Set an interval event to wait for all the pages to load, then show the content + var loading_config = setInterval(function() { + if (config_loaded == 1) { + $("#loading-page").hide(); + $("#everything").show(); + $("#server-content").show(); + $("#server-config").show(); + clearInterval(loading_config); + console.log("Completed configuration initialization."); + } + }, 300); + + }).fail(function(data) { + popup_err("Failed To Contact Server",data.message); + $("#everything").show(); + check_inst_alive(1); + }); +} + +$(window.document).ready(function() { + if(navigator.userAgent.toLowerCase().indexOf('firefoxf') > -1) { + $("select@@@").focus( function() { + this.style.setProperty( 'outline', 'none', 'important' ); + this.style.setProperty( 'color', 'rgba(0,0,0,0)', 'important' ); + this.style.setProperty( 'text-shadow', '0 0 0 #000', 'important' ); + }); + } + $("#plugin-tab").on("click", function() { + cockpit.jump("/389-console/plugins", cockpit.transport.host); + }); +}); + + diff --git a/src/cockpit/389-console/src/fonts/OpenSans-Bold-webfont.woff b/src/cockpit/389-console/src/fonts/OpenSans-Bold-webfont.woff new file mode 100644 index 0000000..f501db0 Binary files /dev/null and b/src/cockpit/389-console/src/fonts/OpenSans-Bold-webfont.woff differ diff --git a/src/cockpit/389-console/src/fonts/OpenSans-Bold-webfont.woff2 b/src/cockpit/389-console/src/fonts/OpenSans-Bold-webfont.woff2 new file mode 100644 index 0000000..34aac6f Binary files /dev/null and b/src/cockpit/389-console/src/fonts/OpenSans-Bold-webfont.woff2 differ diff --git a/src/cockpit/389-console/src/fonts/OpenSans-BoldItalic-webfont.woff2 b/src/cockpit/389-console/src/fonts/OpenSans-BoldItalic-webfont.woff2 new file mode 100644 index 0000000..cc8d731 Binary files /dev/null and b/src/cockpit/389-console/src/fonts/OpenSans-BoldItalic-webfont.woff2 differ diff --git a/src/cockpit/389-console/src/fonts/OpenSans-Italic-webfont.woff b/src/cockpit/389-console/src/fonts/OpenSans-Italic-webfont.woff new file mode 100644 index 0000000..9e17567 Binary files /dev/null and b/src/cockpit/389-console/src/fonts/OpenSans-Italic-webfont.woff differ diff --git a/src/cockpit/389-console/src/fonts/OpenSans-Italic-webfont.woff2 b/src/cockpit/389-console/src/fonts/OpenSans-Italic-webfont.woff2 new file mode 100644 index 0000000..9a96c63 Binary files /dev/null and b/src/cockpit/389-console/src/fonts/OpenSans-Italic-webfont.woff2 differ diff --git a/src/cockpit/389-console/src/fonts/OpenSans-Light-webfont.ttf b/src/cockpit/389-console/src/fonts/OpenSans-Light-webfont.ttf new file mode 100644 index 0000000..0d38189 Binary files /dev/null and b/src/cockpit/389-console/src/fonts/OpenSans-Light-webfont.ttf differ diff --git a/src/cockpit/389-console/src/fonts/OpenSans-Light-webfont.woff b/src/cockpit/389-console/src/fonts/OpenSans-Light-webfont.woff new file mode 100644 index 0000000..fb34cf3 Binary files /dev/null and b/src/cockpit/389-console/src/fonts/OpenSans-Light-webfont.woff differ diff --git a/src/cockpit/389-console/src/fonts/OpenSans-Light-webfont.woff2 b/src/cockpit/389-console/src/fonts/OpenSans-Light-webfont.woff2 new file mode 100644 index 0000000..9a71d1c Binary files /dev/null and b/src/cockpit/389-console/src/fonts/OpenSans-Light-webfont.woff2 differ diff --git a/src/cockpit/389-console/src/fonts/OpenSans-Regular-webfont.ttf b/src/cockpit/389-console/src/fonts/OpenSans-Regular-webfont.ttf new file mode 100644 index 0000000..db43334 Binary files /dev/null and b/src/cockpit/389-console/src/fonts/OpenSans-Regular-webfont.ttf differ diff --git a/src/cockpit/389-console/src/fonts/OpenSans-Regular-webfont.woff b/src/cockpit/389-console/src/fonts/OpenSans-Regular-webfont.woff new file mode 100644 index 0000000..1251d51 Binary files /dev/null and b/src/cockpit/389-console/src/fonts/OpenSans-Regular-webfont.woff differ diff --git a/src/cockpit/389-console/src/fonts/OpenSans-Regular-webfont.woff2 b/src/cockpit/389-console/src/fonts/OpenSans-Regular-webfont.woff2 new file mode 100644 index 0000000..0964c7c Binary files /dev/null and b/src/cockpit/389-console/src/fonts/OpenSans-Regular-webfont.woff2 differ diff --git a/src/cockpit/389-console/src/fonts/OpenSans-Semibold-webfont.ttf b/src/cockpit/389-console/src/fonts/OpenSans-Semibold-webfont.ttf new file mode 100644 index 0000000..1a7679e Binary files /dev/null and b/src/cockpit/389-console/src/fonts/OpenSans-Semibold-webfont.ttf differ diff --git a/src/cockpit/389-console/src/fonts/OpenSans-Semibold-webfont.woff b/src/cockpit/389-console/src/fonts/OpenSans-Semibold-webfont.woff new file mode 100644 index 0000000..409c725 Binary files /dev/null and b/src/cockpit/389-console/src/fonts/OpenSans-Semibold-webfont.woff differ diff --git a/src/cockpit/389-console/src/fonts/OpenSans-Semibold-webfont.woff2 b/src/cockpit/389-console/src/fonts/OpenSans-Semibold-webfont.woff2 new file mode 100644 index 0000000..d088697 Binary files /dev/null and b/src/cockpit/389-console/src/fonts/OpenSans-Semibold-webfont.woff2 differ diff --git a/src/cockpit/389-console/src/fonts/OpenSans-SemiboldItalic-webfont.woff b/src/cockpit/389-console/src/fonts/OpenSans-SemiboldItalic-webfont.woff new file mode 100644 index 0000000..5431477 Binary files /dev/null and b/src/cockpit/389-console/src/fonts/OpenSans-SemiboldItalic-webfont.woff differ diff --git a/src/cockpit/389-console/src/fonts/PatternFlyIcons-webfont.ttf b/src/cockpit/389-console/src/fonts/PatternFlyIcons-webfont.ttf new file mode 100644 index 0000000..1ed274b Binary files /dev/null and b/src/cockpit/389-console/src/fonts/PatternFlyIcons-webfont.ttf differ diff --git a/src/cockpit/389-console/src/fonts/PatternFlyIcons-webfont.woff b/src/cockpit/389-console/src/fonts/PatternFlyIcons-webfont.woff new file mode 100644 index 0000000..8eb1d89 Binary files /dev/null and b/src/cockpit/389-console/src/fonts/PatternFlyIcons-webfont.woff differ diff --git a/src/cockpit/389-console/src/fonts/fontawesome-webfont.woff b/src/cockpit/389-console/src/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/src/cockpit/389-console/src/fonts/fontawesome-webfont.woff differ diff --git a/src/cockpit/389-console/src/fonts/fontawesome-webfont.woff2 b/src/cockpit/389-console/src/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/src/cockpit/389-console/src/fonts/fontawesome-webfont.woff2 differ diff --git a/src/cockpit/389-console/src/fonts/glyphicons-halflings-regular.woff b/src/cockpit/389-console/src/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 0000000..9e61285 Binary files /dev/null and b/src/cockpit/389-console/src/fonts/glyphicons-halflings-regular.woff differ diff --git a/src/cockpit/389-console/src/fonts/glyphicons-halflings-regular.woff2 b/src/cockpit/389-console/src/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 0000000..64539b5 Binary files /dev/null and b/src/cockpit/389-console/src/fonts/glyphicons-halflings-regular.woff2 differ diff --git a/src/cockpit/389-console/src/images/sort_asc.png b/src/cockpit/389-console/src/images/sort_asc.png new file mode 100644 index 0000000..e1ba61a Binary files /dev/null and b/src/cockpit/389-console/src/images/sort_asc.png differ diff --git a/src/cockpit/389-console/src/images/sort_asc_disabled.png b/src/cockpit/389-console/src/images/sort_asc_disabled.png new file mode 100644 index 0000000..fb11dfe Binary files /dev/null and b/src/cockpit/389-console/src/images/sort_asc_disabled.png differ diff --git a/src/cockpit/389-console/src/images/sort_both.png b/src/cockpit/389-console/src/images/sort_both.png new file mode 100644 index 0000000..af5bc7c Binary files /dev/null and b/src/cockpit/389-console/src/images/sort_both.png differ diff --git a/src/cockpit/389-console/src/images/sort_desc.png b/src/cockpit/389-console/src/images/sort_desc.png new file mode 100644 index 0000000..0e156de Binary files /dev/null and b/src/cockpit/389-console/src/images/sort_desc.png differ diff --git a/src/cockpit/389-console/src/images/sort_desc_disabled.png b/src/cockpit/389-console/src/images/sort_desc_disabled.png new file mode 100644 index 0000000..c9fdd8a Binary files /dev/null and b/src/cockpit/389-console/src/images/sort_desc_disabled.png differ diff --git a/src/cockpit/389-console/src/index.html b/src/cockpit/389-console/src/index.html new file mode 100644 index 0000000..895c4ad --- /dev/null +++ b/src/cockpit/389-console/src/index.html @@ -0,0 +1,548 @@ + + + + 389 Directory Server + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/cockpit/389-console/src/manifest.json b/src/cockpit/389-console/src/manifest.json new file mode 100644 index 0000000..50eb6d1 --- /dev/null +++ b/src/cockpit/389-console/src/manifest.json @@ -0,0 +1,13 @@ +{ + "version": "1.0", + "name": "389-console", + "require": { + "cockpit": "137" + }, + "tools": { + "389-console": { + "label": "389 Directory Server", + "path": "index.html" + } + } +} diff --git a/src/cockpit/389-console/src/monitor.html b/src/cockpit/389-console/src/monitor.html new file mode 100644 index 0000000..3feaf0b --- /dev/null +++ b/src/cockpit/389-console/src/monitor.html @@ -0,0 +1,918 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/cockpit/389-console/src/monitor.js b/src/cockpit/389-console/src/monitor.js new file mode 100644 index 0000000..1774d15 --- /dev/null +++ b/src/cockpit/389-console/src/monitor.js @@ -0,0 +1,398 @@ + +var accesslog_cont_refresh; +var auditlog_cont_refresh; +var auditfaillog_cont_refresh; +var errorslog_cont_refresh; + +var sev_emerg = " - EMERG - "; +var sev_crit = " - CRIT - "; +var sev_alert = " - ALERT - "; +var sev_err = " - ERR - "; +var sev_warn = " - WARN - "; +var sev_notice = " - NOTICE - "; +var sev_info = " - INFO - "; +var sev_debug = " - DEBUG - "; +var sev_levels = {"Emergency": sev_emerg, + "Critical": sev_crit, + "Alert": sev_alert, + "Error": sev_err, + "Warning": sev_warn, + "Notice": sev_notice, + "Info": sev_info, + "Debug": sev_debug + }; +var sev_all_errs = [sev_emerg, sev_crit, sev_alert, sev_err]; +var sev_all_info = [sev_warn, sev_notice, sev_info, sev_debug]; + + +function gen_ratio_chart(ratio, chart ) { + var c3ChartDefaults = patternfly.c3ChartDefaults(); + var donutConfig = c3ChartDefaults.getDefaultDonutConfig(ratio + "%"); + var miss = 100 - ratio; + var donut_color = patternfly.pfPaletteColors.lightGreen; + if (ratio < 90) { + donut_color = patternfly.pfPaletteColors.red; + } + donutConfig.bindto = chart; + donutConfig.data = { + type: "donut", + columns: [ + ["Hit Ratio", ratio], + ["Miss", miss], + ], + colors: { + 'Hit Ratio': donut_color, + 'Miss': "#D8D8D8" + }, + order: null + }; + donutConfig.size = { + width: 120, + height: 80 + }; + + c3.generate(donutConfig); +}; + +function gen_util_chart(used, maxsize, hitratio, chart ) { + var c3ChartDefaults = patternfly.c3ChartDefaults(); + var ratio = Math.round((used / maxsize) * 100); + var donutConfig = c3ChartDefaults.getDefaultDonutConfig(ratio + "%"); + var avail = maxsize - used; + donutConfig.bindto = chart; + var donut_color = patternfly.pfPaletteColors.lightGreen; + if (hitratio < 90 && ratio > 90) { + donut_color = patternfly.pfPaletteColors.red; + } + + donutConfig.data = { + type: "donut", + columns: [ + ["Used", used], + ["Available", avail], + ], + colors: { + 'Used': donut_color, + 'Available': "#D8D8D8" + }, + order: null + }; + donutConfig.size = { + width: 120, + height: 80 + }; + c3.generate(donutConfig); +}; + +/* + * Refresh logs + */ +function refresh_access_log () { + var access_log = "/var/log/dirsrv/" + server_id + "/access"; // TODO - get actual log location from config + var lines = $("#accesslog-lines").val(); + var logging = cockpit.spawn(["tail", "-" + lines, access_log], + { "superuser": "try" }).done(function(data) { + $("#accesslog-area").text(data); + }); +} + +function refresh_audit_log () { + var audit_log = "/var/log/dirsrv/" + server_id + "/audit"; // TODO - get actual log location from config + var lines = $("#auditlog-lines").val(); + var logging = cockpit.spawn(["tail", "-" + lines, audit_log], + { "superuser": "try" }).done(function(data) { + $("#auditlog-area").text(data); + }); +} + +function refresh_auditfail_log () { + var auditfail_log = "/var/log/dirsrv/" + server_id + "/auditfail"; // TODO - get actual log location from config + var lines = $("#auditfaillog-lines").val(); + var logging = cockpit.spawn(["tail", "-" + lines, auditfail_log], + { "superuser": "try" }).done(function(data) { + $("#auditfaillog-area").text(data); + }); +} + +function refresh_errors_log () { + var errors_log = "/var/log/dirsrv/" + server_id + "/errors"; // TODO - get actual log location from config + var lines = $("#errorslog-lines").val(); + var sev_level = $("#errorslog-sev-level").val(); + var logging = cockpit.spawn(["tail", "-" + lines, errors_log], + { "superuser": "try" }).done(function(data) { + if (sev_level != "Everything"){ + // Filter Data + var lines = data.split('\n'); + var new_data = ""; + for (var i = 0; i < lines.length; i++){ + var line = ""; + if (sev_level == "Error Messages"){ + for (var lev = 0; lev < sev_all_errs.length; lev++) { + if (lines[i].indexOf(sev_all_errs[lev]) != -1){ + line = lines[i] + "\n"; + } + } + } else if (sev_level == "Info Messages"){ + for (var lev = 0; lev < sev_all_info.length; lev++) { + if (lines[i].indexOf(sev_all_info[lev]) != -1){ + line = lines[i] + "\n"; + } + } + } else if (lines[i].indexOf(sev_levels[sev_level]) != -1){ + line = lines[i] + "\n"; + } + // Add the filtered line to new data + new_data += line; + } + data = new_data; + } + $("#errorslog-area").text(data); + }); +} + + +$(document).ready( function() { + $("#monitor-content").load("monitor.html", function () { + $('#monitor-db-tree').jstree({ + "plugins": [ "contextmenu", "wholerow" ], + }); + + $("#monitor-server-btn").on("click", function() { + $(".all-pages").hide(); + $("#monitor-content").show(); + $("#monitor-server-page").show(); + }); + + $("#monitor-db-btn").on("click", function() { + $(".all-pages").hide(); + $("#monitor-content").show(); + + // TODO - NDN cache prior to 1.4.0 is duplicated under each suffix/backend monitor - + // so we need to bring it forward to the global database stats here + var db_hitratio = '99'; + var ndn_hitratio = '83'; + var ndn_maxsize = '25165824'; + var ndn_cursize = '19891200'; + gen_ratio_chart(db_hitratio, '#monitor-db-cache-hitratio-chart'); + gen_ratio_chart(ndn_hitratio, '#monitor-ndn-cache-hitratio-chart'); + gen_util_chart(ndn_cursize, ndn_maxsize, ndn_hitratio, '#monitor-ndn-cache-util-chart'); + + $("#monitor-db-page").show(); + }); + + + $("#monitor-snmp-btn").on("click", function() { + $(".all-pages").hide(); + $("#monitor-content").show(); + $("#monitor-snmp-page").show(); + }); + + $("#monitor-repl-btn").on("click", function() { + $(".all-pages").hide(); + $("#monitor-content").show(); + $("#monitor-repl-page").show(); + }); + + $("#monitor-log-access-btn").on("click", function() { + $(".all-pages").hide(); + $("#monitor-content").show(); + refresh_access_log(); + $("#monitor-log-access-page").show(); + }); + $("#monitor-log-audit-btn").on("click", function() { + $(".all-pages").hide(); + $("#monitor-content").show(); + refresh_audit_log(); + $("#monitor-log-audit-page").show(); + }); + $("#monitor-log-auditfail-btn").on("click", function() { + $(".all-pages").hide(); + $("#monitor-content").show(); + refresh_auditfail_log() + $("#monitor-log-auditfail-page").show(); + }); + $("#monitor-log-errors-btn").on("click", function() { + $(".all-pages").hide(); + $("#monitor-content").show(); + refresh_errors_log(); + $("#monitor-log-errors-page").show(); + }); + + $("#accesslog-refresh-btn").on('click', function () { + refresh_access_log(); + }); + $("#auditlog-refresh-btn").on('click', function () { + refresh_audit_log(); + }); + $("#auditfaillog-refresh-btn").on('click', function () { + refresh_auditfail_log(); + }); + $("#errorslog-refresh-btn").on('click', function () { + refresh_errors_log(); + }); + + $('#monitor-db-tree').on("changed.jstree", function (e, data) { + var tree_node = data.selected; + if (tree_node == "monitor-db-main") { + + // TODO - NDN cache prior to 1.4.0 is duplicated under each suffix/backend monitor - + // so we need to bring it forward to the global database stats here + var db_hitratio = '99'; + var ndn_hitratio = '83'; + var ndn_maxsize = '25165824'; + var ndn_cursize = '19891200'; + + gen_ratio_chart(db_hitratio, '#monitor-db-cache-hitratio-chart'); + gen_ratio_chart(ndn_hitratio, '#monitor-ndn-cache-hitratio-chart'); + gen_util_chart(ndn_cursize, ndn_maxsize, ndn_hitratio, '#monitor-ndn-cache-util-chart'); + $("#monitor-suffix-page").hide(); + $("#db-content").show(); + } else if (tree_node[0].startsWith("monitor-suffix-")) { + /* + * Gather and set the Suffix info + */ + var monitor_suffix = tree_node[0].replace("monitor-suffix-", ""); + $("#monitor-suffix-header").html("" + monitor_suffix + ""); + + // TODO - get the monitor info. For now uses DEMO values for the charts + var entry_hitratio = '96'; + var entry_maxsize = '512000'; + var entry_cursize = '395000'; + var dn_hitratio = '89'; + var dn_maxsize = '51200'; + var dn_cursize = '51200'; + + // Generate the donut charts + gen_ratio_chart(entry_hitratio, '#monitor-entry-cache-hitratio-chart'); + gen_util_chart(entry_cursize, entry_maxsize, entry_hitratio, '#monitor-entry-cache-util-chart'); + gen_ratio_chart(dn_hitratio, '#monitor-dn-cache-hitratio-chart'); + gen_util_chart(dn_cursize, dn_maxsize, dn_hitratio, '#monitor-dn-cache-util-chart'); + $("#db-content").hide(); + $("#monitor-suffix-page").show(); + } + }); + + var monitor_conn_table = $('#monitor-conn-table').DataTable( { + "paging": true, + "bAutoWidth": false, + "searching": false, + "dom": '<"pull-left"f><"pull-right"l>tip', + "lengthChange": false, + "lengthMenu": [ 10, 25, 50, 100], + "language": { + "emptyTable": "No active connections", + "search": "Search Connections" + } + }); + var monitor_index_table = $('#monitor-index-table').DataTable( { + "paging": true, + "bAutoWidth": false, + "dom": '<"pull-left"f><"pull-right"l>tip', + "lengthMenu": [ 10, 25, 50, 100], + "language": { + "emptyTable": "No Attribute Indexes", + "search": "Search Indexes" + } + }); + + $.fn.dataTable.moment( 'HH:mm:ss' ); + var monitor_repl_table = $('#monitor-repl-table').DataTable( { + "paging": true, + "bAutoWidth": false, + "dom": '<"pull-left"f><"pull-right"l>tip', + "lengthMenu": [ 10, 25, 50, 100], + "language": { + "emptyTable": "No Replication Agreements", + "search": "Search" + } + }); + + var monitor_winsync_table = $('#monitor-winsync-table').DataTable( { + "paging": true, + "bAutoWidth": false, + "dom": '<"pull-left"f><"pull-right"l>tip', + "lengthMenu": [ 10, 25, 50, 100], + "language": { + "emptyTable": "No Winsync Agreements", + "search": "Search" + } + }); + + // The continuous log refresh intervals + $("#accesslog-cont-refresh").change(function() { + if(this.checked) { + accesslog_cont_refresh = setInterval(refresh_access_log, 1000); + } else { + clearInterval(accesslog_cont_refresh); + } + }); + + $("#auditlog-cont-refresh").change(function() { + if(this.checked) { + auditlog_cont_refresh = setInterval(refresh_audit_log, 1000); + } else { + clearInterval(auditlog_cont_refresh); + } + }); + + $("#auditfaillog-cont-refresh").change(function() { + if(this.checked) { + auditfaillog_cont_refresh = setInterval(refresh_auditfail_log, 1000); + } else { + clearInterval(auditfaillog_cont_refresh); + } + }); + + $("#errorslog-cont-refresh").change(function() { + if(this.checked) { + errorslog_cont_refresh = setInterval(refresh_errors_log, 1000); + } else { + clearInterval(errorslog_cont_refresh); + } + }); + + // Refresh page after changing severity level + $("#errorslog-sev-level").on("change", function() { + refresh_errors_log(); + }); + + $(document).on('click', '.repl-detail-btn', function(e) { + e.preventDefault(); + var data = monitor_repl_table.row( $(this).parents('tr') ).data(); + var agmt_name = data[0]; + var agmt_suffix = data[2]; + var agmt_enabled = "off"; // TODO Need to determine this from DS data + var agmt_status = ""; + if (agmt_enabled == "off") { + agmt_status = " (Agreement Disabled)"; + } + // clear_agmt_form(); + + $("#monitor-agmt-header").html("Replication Agreement Details:   " + agmt_name + " " + agmt_status); + + // TODO - get agreement details and populate form + $("#monitor-agmt-form").css('display', 'block'); + }); + + + $(document).on('click', '.repl-winsync-detail-btn', function(e) { + e.preventDefault(); + var data = monitor_repl_table.row( $(this).parents('tr') ).data(); + var agmt_name = data[0]; + var agmt_suffix = data[2]; + var agmt_enabled = "on"; // TODO Need to determine this from DS data + var agmt_status = ""; + if (agmt_enabled == "off") { + agmt_status = " (Agreement Disabled)"; + } + // clear_agmt_form(); + + $("#repl-winsync-agmt-header").html("Winsync Agreement Details:   " + agmt_name + " " + agmt_status); + // TODO - get agreement details and populate form + $("#monitor-winsync-agmt-form").css('display', 'block'); + }); + + // Page is loaded, mark it as so... + monitor_page_loaded = 1; + }); +}); diff --git a/src/cockpit/389-console/src/plugins.es6 b/src/cockpit/389-console/src/plugins.es6 new file mode 100644 index 0000000..4188848 --- /dev/null +++ b/src/cockpit/389-console/src/plugins.es6 @@ -0,0 +1,10 @@ +import React from "react"; +import ReactDOM from "react-dom"; +import { Plugins } from "./plugins.jsx"; + +document.addEventListener("DOMContentLoaded", function() { + ReactDOM.render( + React.createElement(Plugins, {}), + document.getElementById("plugins") + ); +}); diff --git a/src/cockpit/389-console/src/plugins.html b/src/cockpit/389-console/src/plugins.html new file mode 100644 index 0000000..42a3ce2 --- /dev/null +++ b/src/cockpit/389-console/src/plugins.html @@ -0,0 +1,18 @@ + + + Plugins + + + + + + + + + + + + +
+ + diff --git a/src/cockpit/389-console/src/plugins.jsx b/src/cockpit/389-console/src/plugins.jsx new file mode 100644 index 0000000..ffef0af --- /dev/null +++ b/src/cockpit/389-console/src/plugins.jsx @@ -0,0 +1,53 @@ +import cockpit from "cockpit"; +import React from "react"; +import "./plugins.scss"; +import { Checkbox } from "@patternfly/react-core"; + +const _ = cockpit.gettext; + +export class Plugins extends React.Component { + constructor() { + super(); + this.state = { + hostname: _("Unknown"), + checked: true + }; + this.handleChange = this.handleChange.bind(this); + + cockpit + .file("/etc/hostname") + .read() + .done(content => { + this.setState({ hostname: content.trim() }); + }); + } + + handleChange(event) { + this.setState({ checked: event.checked }); + } + + render() { + function go_up() { + cockpit.jump("/389-console", cockpit.transport.host); + } + return ( +
+

Plugins

+

+ {_("Back to main screen")} +

+

+ {cockpit.format( + _("Setting up plugins on server $0"), + this.state.hostname + )} +

+ +
+ ); + } +} diff --git a/src/cockpit/389-console/src/plugins.scss b/src/cockpit/389-console/src/plugins.scss new file mode 100644 index 0000000..87b46f4 --- /dev/null +++ b/src/cockpit/389-console/src/plugins.scss @@ -0,0 +1,3 @@ +p { + font-weight: bold; +} diff --git a/src/cockpit/389-console/src/replication.html b/src/cockpit/389-console/src/replication.html new file mode 100644 index 0000000..d42aefe --- /dev/null +++ b/src/cockpit/389-console/src/replication.html @@ -0,0 +1,739 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/cockpit/389-console/src/replication.js b/src/cockpit/389-console/src/replication.js new file mode 100644 index 0000000..eb378ff --- /dev/null +++ b/src/cockpit/389-console/src/replication.js @@ -0,0 +1,2192 @@ +var repl_suffix = ""; +var prev_repl_role = "no-repl"; +var prev_role_button; +var binddn_list_color = ""; +var repl_mgr_table; +var current_role = ""; +var current_rid = ""; +var repl_agmt_table; +var repl_winsync_agmt_table; +var repl_clean_table; +var repl_agmt_values = {}; +var repl_winsync_agmt_values = {}; +var frac_prefix = "(objectclass=*) $ EXCLUDE"; +var agmt_init_intervals = []; +var agmt_init_counter = 0; +var winsync_init_intervals = []; +var winsync_init_counter = 0; + +// HTML items +var progress_html = '

Initializing Agreement...

'; + +var agmt_action_html = + ''; + +var winsync_agmt_action_html = + ''; + +var cleanallruv_action_html = + ''; + +// Attribute to CLI argument mappings +var repl_attr_map = { + 'nsds5replicaid': '--replica-id', + 'nsds5replicapurgedelay': '--repl-purge-delay', + 'nsds5replicatombstonepurgeinterval': '--repl-tombstone-purge-interval', + 'nsds5replicaprecisetombstonepurging': '--repl-fast-tombstone-purging', + 'nsds5replicabinddngroup': '--repl-bind-group', + 'nsds5replicabinddngroupcheckinterval': '--repl-bind-group-interval', + 'nsds5replicaprotocoltimeout': '--repl-protocol-timeout', + 'nsds5replicabackoffmin': '--repl-backoff-min', + 'nsds5replicabackoffmax': '--repl-backoff-max', + 'nsds5replicareleasetimeout': '--repl-release-timeout', + 'nsds5flags': '', + 'nsds5replicatype': '', + 'nsds5replicabinddn': '', + 'nsslapd-changelogdir': '--cl-dir', + 'nsslapd-changelogmaxentries': '--max-entries', + 'nsslapd-changelogmaxage': '--max-age', + 'nsslapd-changelogcompactdb-interval': '--compact-interval', + 'nsslapd-changelogtrim-interval': '--trim-interval' +}; + +var repl_cl_attrs = ['nsslapd-changelogdir', 'nsslapd-changelogmaxentries', 'nsslapd-changelogmaxage', + 'nsslapd-changelogcompactdb-interval', 'nsslapd-changelogtrim-interval']; + +var repl_attrs = ['nsds5replicaid', 'nsds5replicapurgedelay', 'nsds5replicatombstonepurgeinterval', + 'nsds5replicaprecisetombstonepurging', 'nsds5replicabinddngroup', + 'nsds5replicabinddngroupcheckinterval', 'nsds5replicaprotocoltimeout', 'nsds5replicabackoffmin', + 'nsds5replicabackoffmax', 'nsds5replicareleasetimeout']; + + +// Helper functions +function clear_agmt_wizard () { + // Clear input fields and reset dropboxes + $('.ds-agmt-schedule-checkbox').prop('checked', false); + $('#agmt-schedule-checkbox').prop('checked', true); + $("#agmt-start-time").val("00:00"); + $("#agmt-end-time").val("00:15"); + $(".ds-agmt-wiz-dropdown").prop('selectedIndex',0); + $(".ds-agmt-panel").css('display','none'); + $(".agmt-form-input").css("border-color", "initial"); + $(".agmt-form-input").val(""); + $('#frac-exclude-list').find('option').remove(); + $('#frac-exclude-tot-list').find('option').remove(); + $('#frac-strip-list').find('option').remove(); + load_schema_objects_to_select('attributetypes', 'select-attr-list'); + $("#select-attr-list").prop('selectedIndex',-1); + $("#init-options").prop("selectedIndex", 0); + $("#init-agmt-dropdown").show(); + $("#agmt-wizard-title").html("Create Replication Agreement"); +}; + +function clear_enable_repl_form () { + $("#nsds5replicaid-form").css("border-color", "initial"); + $("#nsds5replicaid-form").val(""); + $("#select-enable-repl-role").prop("selectedIndex", 0); + $("#enable-repl-pw").val(""); + $("#enable-repl-pw-confirm").val(""); + $("#enable-repl-mgr-dn").val(""); + $("#enable-repl-mgr-checkbox").prop('checked', false); + $("#enable-repl-mgr-passwd").hide(); +} + +function clear_winsync_agmt_wizard() { + // Clear out winsync agreement form + $("#winsync-agmt-cn").val(""); + $("#winsync-nsds7windowsdomain").val(""); + $("#winsync-nsds5replicahost").val(""); + $("#winsync-nsds5replicaport").val(""); + $("#winsync-nsds7windowsreplicasubtree").val(""); + $("#winsync-nsds7directoryreplicasubtree").val(""); + $("#winsync-nsds7newwinusersyncenabled-checkbox").prop('checked', false); + $("#winsync-nsds7newwingroupsyncenabled-checkbox").prop('checked', false); + $("#winsync-init-checkbox").prop('checked', false); + $("#winsync-init-chbx").show(); + $("#winsync-nsds5replicabinddn").val(""); + $("#winsync-nsds5replicacredentials").val(""); + $("#winsync-nsds5replicacredentials-confirm").val(""); + $("#winsync-nsds5replicatransportinfo").prop('selectedIndex', 0); + $("#winsync-agmt-wizard-title").html("Create Winsync Agreement"); +} + +function clear_cleanallruv_form () { + // Clear input fields and reset dropboxes + $('#force-clean').prop('checked', true); + $("#cleanallruv-rid").val(""); +}; + +function clear_repl_mgr_form () { + $("#add-repl-pw").val(""); + $("#add-repl-pw-confirm").val(""); + $("#add-repl-mgr-dn").val("cn=replication manager,cn=config"); + $("#add-repl-mgr-checkbox").prop('checked', false); + $("#add-repl-mgr-passwd").hide(); +} + + +function add_repl_mgr(dn){ + // First check if manager is set to none + $("#repl-mgr-table tbody").append( + ""+ + "" + dn +""+ + ""+ + "" + + ""); +}; + + +function do_agmt_init(suffix, agmt_cn, idx) { + var status_cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'init-status', '--suffix=' + suffix, '"' + agmt_cn + '"' ]; + log_cmd('do_agmt_init', 'Get initialization status for agmt', status_cmd); + cockpit.spawn(status_cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + var init_stat = JSON.parse(data); + if (init_stat == 'Agreement successfully initialized.' || + init_stat == 'Agreement initialization failed.') + { + // Init is done (good or bad) + get_and_set_repl_agmts(); + clearInterval(agmt_init_intervals[idx]); + } + }); +} + +function do_winsync_agmt_init(suffix, agmt_cn, idx) { + var status_cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-winsync-agmt', 'init-status', '--suffix=' + suffix, '"' + agmt_cn + '"' ]; + log_cmd('do_winsync_agmt_init', 'Get initialization status for agmt', status_cmd); + cockpit.spawn(status_cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + var init_stat = JSON.parse(data); + if (init_stat == 'Agreement successfully initialized.' || + init_stat == 'Agreement initialization failed.') + { + // Init is done (good or bad) + get_and_set_repl_winsync_agmts(); + clearInterval(agmt_init_intervals[idx]); + } + }); +} + +function get_and_set_repl_winsync_agmts() { + /* + * Get the replication agreements for the selected suffix + */ + var suffix = $("#select-repl-winsync-suffix").val(); + repl_winsync_agmt_table.clear(); + + if (suffix) { + console.log("Loading winsync replication agreements..."); + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-winsync-agmt', 'list', '--suffix=' + suffix ]; + log_cmd('get_and_set_repl_winsync_agmts', 'Get the winsync agmts', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + var obj = JSON.parse(data); + for (var idx in obj['items']) { + var state = "Enabled"; + var con_host = ""; + var con_port = ""; + var ds_subtree = ""; + var win_subtree = ""; + agmt_attrs = obj['items'][idx]['attrs']; + var agmt_name = agmt_attrs['cn'][0]; + + // Compute state (enabled by default) + if ('nsds5replicaenabled' in agmt_attrs) { + if (agmt_attrs['nsds5replicaenabled'][0].toLowerCase() == 'off'){ + state = "Disabled"; + } + } + var ws_agmt_init_status = "Initialized"; + if ('nsds5replicalastinitstatus' in agmt_attrs && + agmt_attrs['nsds5replicalastinitstatus'][0] != "") + { + ws_agmt_init_status = agmt_attrs['nsds5replicalastinitstatus'][0]; + if (ws_agmt_init_status == "Error (0) Total update in progress" || + ws_agmt_init_status == "Error (0)") + { + ws_agmt_init_status = progress_html; + var ws_interval_agmt_name = agmt_name; + var ws_init_status_interval = setInterval(function() { + var status_cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-winsync-agmt', 'init-status', '--suffix=' + suffix, '"' + ws_interval_agmt_name + '"' ]; + log_cmd('get_and_set_repl_winsync_agmts', 'Get initialization status for winsync agmt', status_cmd); + cockpit.spawn(status_cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + var init_stat = JSON.parse(data); + if (init_stat == 'Agreement successfully initialized.' || + init_stat == 'Agreement initialization failed.') + { + // Init is done (good or bad) + get_and_set_repl_winsync_agmts(); + clearInterval(ws_init_status_interval); + } + }); + }, 2000); + } else if (ws_agmt_init_status == "Error (0) Total update succeeded") { + ws_agmt_init_status = "Initialized"; + } + } else if (agmt_attrs['nsds5replicalastinitstart'][0] == "19700101000000Z"){ + ws_agmt_init_status = "Not initialized"; + } + + repl_winsync_agmt_table.row.add( [ + agmt_attrs['cn'][0], + agmt_attrs['nsds5replicahost'][0], + agmt_attrs['nsds5replicaport'][0], + state, + agmt_attrs['nsds5replicalastupdatestatus'][0], + ws_agmt_init_status, + winsync_agmt_action_html + ] ).draw( false ); + console.log("Finished loading winsync replication agreements."); + } + }); + } // suffix +} + + +function get_and_set_repl_agmts () { + /* + * Get the replication agreements for the selected suffix + */ + var suffix = $("#select-repl-agmt-suffix").val(); + + if (suffix) { + console.log("Loading replication agreements..."); + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'list', '--suffix=' + suffix ]; + log_cmd('get_and_set_repl_agmts', 'Get replication agreements', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + repl_agmt_table.clear().draw(); + var obj = JSON.parse(data); + for (var idx in obj['items']) { + agmt_attrs = obj['items'][idx]['attrs']; + var agmt_name = agmt_attrs['cn'][0]; + var state = "Enabled"; + var update_status = ""; + var agmt_init_status = "Initialized"; + + // Compute state (enabled by default) + if ('nsds5replicaenabled' in agmt_attrs) { + if (agmt_attrs['nsds5replicaenabled'][0].toLowerCase() == 'off'){ + state = "Disabled"; + } + } + + // Check for status msgs + if ('nsds5replicalastupdatestatus' in agmt_attrs) { + update_status = agmt_attrs['nsds5replicalastupdatestatus'][0]; + } + if ('nsds5replicalastinitstatus' in agmt_attrs && + agmt_attrs['nsds5replicalastinitstatus'][0] != "") + { + agmt_init_status = agmt_attrs['nsds5replicalastinitstatus'][0]; + if (agmt_init_status == "Error (0) Total update in progress" || + agmt_init_status == "Error (0)") + { + agmt_init_status = progress_html; + var interval_agmt_name = agmt_name; + var init_idx = agmt_init_counter; + agmt_init_counter += 1; + agmt_init_intervals[init_idx] = setInterval( do_agmt_init, 2000, suffix, interval_agmt_name, init_idx); + } else if (agmt_init_status == "Error (0) Total update succeeded") { + agmt_init_status = "Initialized"; + } + } else if (agmt_attrs['nsds5replicalastinitstart'][0] == "19700101000000Z"){ + agmt_init_status = "Not initialized"; + } + + // Update table + repl_agmt_table.row.add( [ + agmt_attrs['cn'][0], + agmt_attrs['nsds5replicahost'][0], + agmt_attrs['nsds5replicaport'][0], + state, + update_status, + agmt_init_status, + agmt_action_html + ] ).draw( false ); + } + console.log("Finished loading replication agreements."); + }).fail(function () { + repl_agmt_table.clear().draw(); + }); + } // suffix +} + + +function get_and_set_cleanallruv() { + console.log("Loading replication tasks..."); + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-tasks', 'list-cleanallruv']; + log_cmd('get_and_set_cleanallruv', 'Get the cleanAllRUV tasks', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + var tasks = JSON.parse(data); + repl_clean_table.clear().draw(); + for (var idx in tasks['items']) { + task_attrs = tasks['items'][idx]['attrs']; + // Update table + var abort_btn = cleanallruv_action_html; + if (task_attrs['nstaskstatus'][0].includes('Successfully cleaned rid') ){ + abort_btn = "Task Complete"; + } else if (task_attrs['nstaskstatus'][0].includes('Task aborted for rid') ){ + abort_btn = "Task Aborted"; + } + repl_clean_table.row.add( [ + task_attrs['cn'][0], + get_date_string(task_attrs['createtimestamp'][0]), + task_attrs['replica-base-dn'][0], + task_attrs['replica-id'][0], + task_attrs['nstaskstatus'][0], + abort_btn + ] ); + } + repl_clean_table.draw(false); + console.log("Finished loading replication tasks."); + }); +} + + +function get_and_set_repl_config () { + var suffix = $("#select-repl-cfg-suffix").val(); + + if (suffix) { + $("#nsds5replicaid").css("border-color", "initial"); + repl_config_values = {}; + console.log("Loading replication configuration..."); + + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'get', '--suffix=' + suffix ]; + log_cmd('get_and_set_repl_config', 'Get replication configuration', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + var repl = JSON.parse(data); + var repl_type; + var repl_flags; + var manager = false; + $('#repl-mgr-table').find("tr:gt(0)").remove(); + $(".ds-cfg").val(""); + $("#nsds5replicaprecisetombstonepurging").prop('checked', false); + + // Set configuration and the repl manager table + for (var attr in repl['attrs']) { + var vals = repl['attrs'][attr]; + attr = attr.toLowerCase(); + + if (attr in repl_attr_map) { + if (attr == "nsds5replicabinddn") { + // update manager table + for (var val_idx in vals){ + add_repl_mgr(vals[val_idx]); + manager = true; + } + } else if (attr == "nsds5replicatype") { + repl_type = vals[0]; + } else if (attr == "nsds5flags") { + repl_flags = vals[0]; + } else { + // Regular attribute + if (vals[0] == "on") { + $("#" + attr).prop('checked', true); + $("#" + attr).trigger('change'); + } else if (vals[0] == "off") { + $("#" + attr).prop('checked', false); + $("#" + attr).trigger('change'); + } + $("#" + attr ).val(vals[0]); + repl_config_values[attr] = vals[0]; + } + } + } + if (!manager) { + // Add an empty row to define the table + $("#repl-mgr-table tbody").append( + ""+ + "None"+ + "" + + ""); + } + + // Set the replica role + if (repl_type == "3"){ + $("#select-repl-role").val("Master"); + current_role = "Master"; + $("#nsds5replicaid").show(); + $("#replicaid-label").show(); + } else { + $("#nsds5replicaid").hide(); + $("#replicaid-label").hide(); + if (repl_flags == "1"){ + $("#select-repl-role").val("Hub"); + current_role = "Hub"; + } else { + $("#select-repl-role").val("Consumer"); + current_role = "Consumer"; + } + } + current_rid = $("#nsds5replicaid").val(); + + // Show the page (in case it was hidden) + $("#ds-repl-enabled").hide(); + $("#repl-config-content").show(); + + console.log("Finished loading replication configuration."); + }).fail(function(data) { + // No replication + current_role = "Disabled"; + $("#repl-config-content").hide(); + $("#ds-repl-enabled").show(); + }); + } else { + // No Suffix + $("#repl-config-content").hide(); + $("#ds-repl-enabled").hide(); + } + + // Do the changelog settings + $("#cl-create-div").show(); + $("#cl-del-div").hide(); + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'get-changelog']; + log_cmd('get_and_set_repl_config', 'Get replication changelog', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + $(".ds-cl").val(""); // Clear form + var cl = JSON.parse(data); + repl_cl_values = {}; + for (var attr in cl['attrs']) { + var val = cl['attrs'][attr][0]; + attr = attr.toLowerCase(); + $("#" + attr ).val(val); + $("#cl-create-div").hide(); + $("#cl-del-div").show(); + repl_cl_values[attr] = val; + } + }).fail(function() { + // No changelog, clear the form + $(".ds-cl").val(""); + }); +} + + +function save_repl_config(suffix, ignore_rid) { + /* + * Check for changes in the replication settings + */ + var set_repl_values = {}; + var set_cl_values = {}; + var arg_list = []; + for (var attr in repl_attrs) { + attr = repl_attrs[attr]; + var val = ""; + if ( $("#" + attr).is(':checkbox')) { + if ( $("#" + attr).is(":checked")) { + val = "on"; + } else { + val = "off"; + } + } else { + val = $("#" + attr).val(); + } + var prev_val = ""; + + if (attr in repl_config_values) { + prev_val = repl_config_values[attr]; + } + + if (val != prev_val) { + if (attr == "nsds5replicaid"){ + // skip it since we are doing a promotion + continue; + } + // Handle checkbox input + if ( $("#" + attr).is(':checkbox')) { + if ( $("#" + attr).is(":checked")) { + arg_list.push(repl_attr_map[attr] + "=" + "on" ); + } else { + // Not checked + arg_list.push(repl_attr_map[attr] + "=" + "off" ); + } + } else { + // Regular input + if (val != "") { + // Regular setting - add to the list + arg_list.push(repl_attr_map[attr] + "=" + val ); + } else { + // removed + arg_list.push(repl_attr_map[attr] + "="); + } + } + set_repl_values[attr] = val; + } + } + + /* + * Check for changes in the changelog settings + */ + var arg_cl_list = []; + for (var attr in repl_cl_attrs) { + attr = repl_cl_attrs[attr]; + var val = $("#" + attr).val(); + var prev_val = ""; + if (attr in repl_cl_values) { + prev_val = repl_cl_values[attr]; + } + if (val != prev_val) { + // we have a difference + if (val != "") { + // Regular setting -add to the list + arg_cl_list.push(repl_attr_map[attr] + "=" + val); + } else { + // removed + arg_cl_list.push(repl_attr_map[attr] + "="); + } + set_cl_values[attr] = val; + } + } + + /* + * Save repl config settings + */ + if (arg_list.length > 0){ + + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'set', '--suffix=' + suffix ]; + cmd = cmd.concat(arg_list); + log_cmd('save_repl_config', 'Set replication configuration', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + popup_success('Saved replication configuration'); + for (var key in set_repl_values) { + // Update current in memory values + repl_config_values[key] = set_repl_values[key]; + } + /* + * Save changelog settings + */ + if (arg_cl_list.length > 0){ + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication' ,'set-changelog']; + cmd = cmd.concat(arg_cl_list); + log_cmd('save_repl_config', 'Set changelog configuration', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + popup_success('Saved changelog configuration'); + for (var key in set_cl_values) { + // Update current in memory values + repl_cl_values[key] = set_cl_values[key]; + } + get_and_set_repl_config(); + }).fail(function(data) { + get_and_set_repl_config(); + popup_err("Failed to save changelog configuration", data.message); + }); + } else { + // No changelog changes, so we're done, refresh the settings + get_and_set_repl_config(); + } + }).fail(function(data) { + // Restore prev values + get_and_set_repl_config(); + popup_err("Failed to set replication configuration", data.message); + }); + } else if (arg_cl_list.length > 0) { + /* + * Only changelog settings need to be applied + */ + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication' ,'set-changelog']; + cmd = cmd.concat(arg_cl_list); + log_cmd('save_repl_config', 'Set changelog configuration', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + popup_success('Saved changelog configuration'); + for (var key in set_cl_values) { + // Update current in memory values + repl_cl_values[key] = set_cl_values[key]; + } + get_and_set_repl_config(); + }).fail(function(data) { + get_and_set_repl_config(); + popup_err("Failed to save changelog configuration", data.message); + }); + } +} + + +/* + * Load the replication page, and set the handlers + */ +$(document).ready( function() { + $("#replication-content").load("replication.html", function () { + // Set up agreement table + repl_agmt_table = $('#repl-agmt-table').DataTable( { + "paging": true, + "bAutoWidth": false, + "dom": '<"pull-left"f><"pull-right"l>tip', + "lengthMenu": [ 10, 25, 50, 100], + "language": { + "emptyTable": "No agreements configured", + "search": "Search Agreements" + }, + "columnDefs": [ { + "targets": 6, + "orderable": false + } ], + "columns": [ + { "width": "20%" }, + { "width": "20%" }, + { "width": "50px" }, + { "width": "50px" }, + { "width": "20%" }, + { "width": "20%" }, + { "width": "130px" } + ], + }); + + // Set up windows sync agreement table + repl_winsync_agmt_table = $('#repl-winsync-agmt-table').DataTable( { + "paging": true, + "bAutoWidth": false, + "dom": '<"pull-left"f><"pull-right"l>tip', + "lengthMenu": [ 10, 25, 50, 100], + "language": { + "emptyTable": "No winsync agreements configured", + "search": "Search Agreements" + }, + "columnDefs": [ { + "targets": 6, + "orderable": false + } ] + }); + + // Set up CleanAllRUV Table + repl_clean_table = $('#repl-clean-table').DataTable( { + "paging": true, + "searching": false, + "bAutoWidth": false, + "dom": 'B<"pull-left"f><"pull-right"l>tip', + buttons: [ + { + text: 'Refresh Task List', + action: function ( e, dt, node, config ) { + console.log("hmmm"); + get_and_set_cleanallruv(); + } + } + ], + "lengthChange": false, + "language": { + "emptyTable": "No CleanAllRUV tasks", + }, + "columnDefs": [ { + "targets": 5, + "orderable": false + } ] + }); + + binddn_list_color = $("#repl-managers-list").css("border-color"); + + // Load existing replication config (if any), set role, etc + + $("#schedule-settings").hide(); + + $("#repl-config-btn").on("click", function() { + $(".all-pages").hide(); + $("#replication-content").show(); + $("#repl-config").show(); + }); + + $("#repl-agmts-btn").on("click", function() { + $(".all-pages").hide(); + $("#replication-content").show(); + $("#repl-agmts").show(); + }); + + $("#repl-winsync-btn").on("click", function() { + $(".all-pages").hide(); + $("#replication-content").show(); + $("#repl-winsync").show(); + }); + $("#repl-cleanallruv-btn").on("click", function() { + $(".all-pages").hide(); + $("#replication-content").show(); + $("#repl-cleanallruv").show(); + }); + + $("#select-repl-cfg-suffix").on("change", function() { + get_and_set_repl_config(); + }); + + $("#select-repl-agmt-suffix").on("change", function() { + get_and_set_repl_agmts(); + }); + + $("#select-repl-winsync-suffix").on("change", function() { + get_and_set_repl_winsync_agmts(); + }); + + $("#select-repl-role").on("change", function() { + var new_role = $(this).val(); + if (new_role == "Master"){ + if (current_role != new_role) { + // Reset replica ID for a new master + $("#nsds5replicaid").val("0"); + } + $("#nsds5replicaid").show(); + $("#replicaid-label").show(); + $("#repl-config-content").show(); + } else { + $("#nsds5replicaid").hide(); + $("#replicaid-label").hide(); + $("#repl-config-content").show(); + $("#nsds5replicaid").css("border-color", "initial"); + } + }); + + $("#enable-repl-btn").on('click', function () { + clear_enable_repl_form(); + }); + + /* + * Enable replication - select role dynamics + */ + $("#select-enable-repl-role").on("change", function() { + var new_role = $(this).val(); + if (new_role == "Master"){ + $("#repl-rid-form").show(); + } else { + $("#repl-rid-form").hide(); + } + }); + /* + * Enable replication - save it + */ + $("#enable-repl-save").on('click', function () { + var suffix = $("#select-repl-cfg-suffix").val(); + var role = $("#select-enable-repl-role").val(); + var repl_dn = $("#enable-repl-mgr-dn").val(); + var repl_pw = $("#enable-repl-pw").val(); + var repl_pw_confirm = $("#enable-repl-pw-confirm").val(); + var repl_group = $("#enable-bindgroupdn").val(); + var cmd = []; + + // Validate all the inputs + if (role == "Master") { + // Master role, get and valid replica id + var rid = $("#nsds5replicaid-form").val(); + if (rid == ""){ + $("#nsds5replicaid-form").css("border-color", "red"); + popup_msg("Missing Replica ID", + "A Master replica requires a unique identifier. " + + "Please enter a value for Replica ID between 1 and 65534"); + return; + } + if (valid_num(rid)){ + if (rid < 1 || rid >= 65535){ + $("#nsds5replicaid-form").css("border-color", "red"); + popup_msg("Invalid Replica ID", + "A Master replica requires a unique identifier. " + + "Please enter a value for Replica ID between 1 and 65534"); + return; + } + } else { + $("#nsds5replicaid-form").css("border-color", "red"); + popup_msg("Replica ID is not a number", + "A Master replica requires a unique identifier. " + + "Please enter a value for Replica ID between 1 and 65534"); + return; + } + $("#nsds5replicaid-form").css("border-color", "initial"); + cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'enable', + '--suffix=' + suffix, '--role=' + role, '--replica-id=' + rid]; + } else { + // Hub or Consumer - must have a bind dn/group + if (repl_dn == "" && repl_group == ""){ + popup_msg("Attention!", "Replication Manager or Replication Bind Group is required"); + return; + } + cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'enable', + '--suffix=' + suffix, '--role=' + role]; + } + + if (repl_dn != ''){ + if (repl_pw != repl_pw_confirm) { + popup_msg("Attention!", "Passwords do not match"); + $("#enable-repl-pw").val(""); + $("#enable-repl-pw-confirm").val(""); + return; + } + if (!valid_dn(repl_dn)) { + popup_msg("Attention!", "Invalid DN for Replication Manager"); + return; + } + cmd.push.apply(cmd, ['--bind-dn=' + repl_dn]); + cmd.push.apply(cmd, ['--bind-passwd=' + repl_pw]); + } + if (repl_group != ""){ + if (!valid_dn(repl_group)){ + popup_msg("Attention!", "Invalid DN for Replication Bind Group"); + return; + } + cmd.push.apply(cmd, ['--bind-group-dn=' + repl_group]); + } + + // Enable replication finally + log_cmd('#enable-repl-save (click)', 'Enable replication', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + // Replication has been enabled + popup_success("Successfully enabled replication"); + $("#enable-repl-form").modal('toggle'); + get_and_set_repl_config(); + }).fail(function(data) { + // Undo what we have done + popup_err("Failed to enable replication", data.message); + var disable_cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'disable', '--suffix=' + suffix ]; + log_cmd('#enable-repl-save (click)', 'Disable replication after error', disable_cmd); + cockpit.spawn(disable_cmd, { superuser: true, "err": "message", "environ": [ENV]}).always(function(data) { + get_and_set_repl_config(); + $("#enable-repl-form").modal('toggle'); + }); + }); + }); + + /* + * Disable replication + */ + $("#disable-repl-btn").on('click', function () { + var suffix = $("#select-repl-cfg-suffix").val(); + popup_confirm("Are you sure you want to disable replication? This will remove all your replication agreements and can not be undone!", "Confirmation", function (yes) { + if (yes) { + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'disable', '--suffix=' + suffix ]; + log_cmd('#disable-repl-btn (click)', 'Disable replication', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + current_role = "Disabled"; + $("#repl-config-content").hide(); + popup_success('Successfully disabled replication'); + get_and_set_repl_config(); + }).fail(function(data) { + popup_err("Failed to disable replication", data.message); + get_and_set_repl_config(); + }); + } + }); + }); + + /* + * Save replication configuration + */ + $("#repl-config-save").on('click', function () { + var suffix = $("#select-repl-cfg-suffix").val(); + var rid = $("#nsds5replicaid").val(); + + if (suffix) { + /* + * Did we config change, promote, or demote this replica? + */ + var new_role = $("#select-repl-role").val(); + if (new_role != current_role) { + /* + * Promote/demote the replica + */ + popup_confirm("Are you sure you want to change the replication role to \"" + new_role + "\"?", "Confirmation", function (yes) { + if (yes) { + if (new_role == "Master"){ + /* + * Promote to Master + */ + if ( !valid_num(rid) ) { + popup_msg("Invalid Replica ID", + "A Master replica requires a unique numerical identifier. Please enter a value for Replica ID between 1 and 65534"); + get_and_set_repl_config(); + return; + } + var rid_num = parseInt(rid, 10); + if (rid_num < 1 || rid_num >= 65535){ + popup_msg("Missing Required Replica ID", + "A Master replica requires a unique numerical identifier. Please enter a value for Replica ID between 1 and 65534"); + get_and_set_repl_config(); + return; + } + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'promote', + '--suffix=' + suffix, "--newrole=" + new_role, "--replica-id=" + rid]; + log_cmd('#repl-config-save (click)', 'Promote replica to Master', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + current_role = "Master";; + popup_success('Successfully promoted replica to a Master'); + get_and_set_repl_config(); + save_repl_config(suffix, true); + }).fail(function(data) { + popup_err("Failed to promote replica to a Master", data.message); + get_and_set_repl_config(); + }); + } else if (new_role == "Hub" && current_role == "Master"){ + /* + * Demote to Hub, but first check that we have a replication manager + */ + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'get', '--suffix=' + suffix ]; + log_cmd('get_and_set_repl_config', 'Get replication configuration', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + var repl = JSON.parse(data); + var manager = false; + for (var attr in repl['attrs']) { + if (attr.toLowerCase() == "nsds5replicabinddn") { + manager = true; + break; + } + } + if (manager == false) { + popup_msg("Missing Required Setting", + "You must create a replication manager before you can demote this replica to a Hub"); + return; + } + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'demote', + '--suffix=' + suffix, "--newrole=" + new_role]; + log_cmd('#repl-config-save (click)', 'Demote replica to Hub', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + current_role = "Hub"; + popup_success('Successfully demoted replica to a Hub'); + save_repl_config(suffix, true); + }).fail(function(data) { + popup_err("Failed to demote replica to a Hub", data.message); + get_and_set_repl_config(); + }); + }); + } else if (new_role == "Hub" && current_role == "Consumer"){ + /* + * Promote to Hub + */ + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'promote', + '--suffix=' + suffix, "--newrole=" + new_role]; + log_cmd('#repl-config-save (click)', 'Promote replica to Hub ', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + current_role = "Hub";; + popup_success('Successfully promoted replica to a Hub'); + save_repl_config(suffix, true); + }).fail(function(data) { + popup_err("Failed to promote replica to a Hub", data.message); + get_and_set_repl_config(); + }); + } else { + /* + * Demote to Consumer, but first confirm we have a replication manager + */ + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'get', '--suffix=' + suffix ]; + log_cmd('get_and_set_repl_config', 'Get replication configuration', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + var repl = JSON.parse(data); + var manager = false; + for (var attr in repl['attrs']) { + if (attr.toLowerCase() == "nsds5replicabinddn") { + manager = true; + break; + } + } + if (manager == false) { + popup_msg("Missing Required Setting", + "You must create a replication manager before you can demote this replica to a Consumer."); + return; + } + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', 'demote', + '--suffix=' + suffix, "--newrole=" + new_role]; + log_cmd('#repl-config-save (click)', 'Demote replication to Consumer', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + current_role = "Consumer"; + popup_success('Successfully demoted replica to a Consumer'); + save_repl_config(suffix, true); + }).fail(function(data) { + popup_err("Failed to demote replica to a Consumer", data.message); + get_and_set_repl_config(); + }); + }); + } + } else { + // Not changing the role - reset the dropdown + $("#select-repl-role").val(current_role); + get_and_set_repl_config(); + } + }); // popup_confirm + } else { + /* + * We did NOT promote/demote, etc. This was just a configuration change... + */ + save_repl_config(suffix, false); + } + } // Suffix + }); + + // Create changelog + $("#create-cl-btn").on('click', function () { + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication' ,'create-changelog']; + log_cmd('#create-cl-btn (click)', 'Create replication changelog', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + get_and_set_repl_config(); + popup_success('Successfully created replication changelog'); + }).fail(function(data) { + get_and_set_repl_config(); + popup_err("Failed to create replication changelog", data.message); + }); + }); + + // Remove changelog + $("#delete-cl-btn").on('click', function () { + popup_confirm("Are you sure you want to delete the replication changelog as it will break all the existing agreements?", "Confirmation", function (yes) { + if (yes) { + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication' ,'delete-changelog']; + log_cmd('#delete-cl-btn (click)', 'Delete replication changelog', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + get_and_set_repl_config(); + popup_success('Successfully removed replication changelog'); + }).fail(function(data) { + get_and_set_repl_config(); + popup_err("Failed to remove replication changelog", data.message); + }); + } + }); + }); + + // Save Repl Agreement Wizard + $("#agmt-save").on("click", function() { + // Get all the settings + var suffix = $("#select-repl-agmt-suffix").val(); + var cmd = []; + var cmd_args = []; + var param_err = false; + var agmt_name = $("#agmt-cn").val(); + var agmt_host = $("#nsds5replicahost").val(); + var agmt_port = $("#nsds5replicaport").val(); + var agmt_bind = $("#nsds5replicabinddn").val(); + var agmt_bindpw = $("#nsds5replicacredentials").val(); + var agmt_bindpw_confirm = $("#nsds5replicacredentials-confirm").val(); + var agmt_conn = $("#nsds5replicatransportinfo").val(); + var agmt_method = $("#nsds5replicabindmethod").val(); + var agmt_schedule = ""; + var agmt_init = $("#init-options").val(); + var agmt_exclude = ""; + var agmt_tot_exclude = ""; + var agmt_strip = ""; + var editing = false; + var init_replica = false; + + if ($("#agmt-wizard-title").text().includes('Edit') ) { + editing = true; + } + + // Check required settings + if ( agmt_port == "") { + $("#nsds5replicaport").css("border-color", "red"); + param_err = true; + } else { + $("#nsds5replicaport").css("border-color", "initial"); + cmd_args.push("--port=" + agmt_port); + } + if ( agmt_host == "") { + $("#nsds5replicahost").css("border-color", "red"); + param_err = true; + } else { + $("#nsds5replicahost").css("border-color", "initial"); + cmd_args.push('--host=' + agmt_host); + } + if ( agmt_conn == "") { + $("#nsds5replicatransportinfo").css("border-color", "red"); + param_err = true; + } else { + $("#nsds5replicatransportinfo").css("border-color", "initial"); + cmd_args.push('--conn-protocol=' + agmt_conn); + } + if ( agmt_method == "") { + $("#nsds5replicabindmethod").css("border-color", "red"); + param_err = true; + } else { + $("#nsds5replicabindmethod").css("border-color", "initial"); + cmd_args.push('--bind-method=' + agmt_method); + } + if ( agmt_bind == "") { + $("#nsds5replicabinddn").css("border-color", "red"); + param_err = true; + } else { + $("#nsds5replicabinddn").css("border-color", "initial"); + cmd_args.push('--bind-dn=' + agmt_bind); + } + if (param_err ){ + popup_msg("Error", "Missing required parameters"); + return; + } + + /* + * Handle the optional settings + */ + $("#frac-exclude-list option").each(function() { + agmt_exclude += $(this).val() + " "; + }); + $("#frac-exclude-tot-list option").each(function() { + agmt_tot_exclude += $(this).val() + " "; + }); + $("#frac-strip-list option").each(function() { + agmt_strip += $(this).val() + " "; + }); + + if (agmt_bindpw != agmt_bindpw_confirm) { + popup_msg("Attention!", "Passwords do not match"); + return; + } + + // Bind Password + if (!editing ){ + if (agmt_bindpw != "") { + cmd_args.push('--bind-passwd=' + agmt_bindpw); + } + } else { + if ( !('nsds5replicacredentials' in repl_agmt_values) || + agmt_bindpw != repl_agmt_values['nsds5replicacredentials']) + { + cmd_args.push('--bind-passwd="' + agmt_bindpw); + } + } + // Frac attrs + agmt_exclude = agmt_exclude.trim(); + if (!editing) { + if (agmt_exclude != "") { + cmd_args.push('--frac-list='+ agmt_exclude); + } + } else { + if ( !('nsds5replicatedattributelist' in repl_agmt_values) || + agmt_exclude != repl_agmt_values['nsds5replicatedattributelist'].replace(frac_prefix, "")) + { + cmd_args.push('--frac-list=' + frac_prefix + ' ' + agmt_exclude); + } + } + // Frac total attr + agmt_tot_exclude = agmt_tot_exclude.trim(); + if (!editing) { + if (agmt_tot_exclude != "") { + cmd_args.push('--frac-list-total='+ agmt_tot_exclude); + } + } else { + if ( !('nsds5replicatedattributelisttotal' in repl_agmt_values) || + agmt_tot_exclude != repl_agmt_values['nsds5replicatedattributelisttotal'].replace(frac_prefix, "")); + { + cmd_args.push('--frac-list-total=' + frac_prefix + ' ' + agmt_tot_exclude); + } + } + // Strip attrs + agmt_strip = agmt_strip.trim(); + if (!editing) { + if (agmt_strip != "") { + cmd_args.push('--strip-list='+ agmt_strip); + } + } else { + if ( !('nsds5replicastripattrs' in repl_agmt_values) || + agmt_strip != repl_agmt_values['nsds5replicastripattrs']); + { + cmd_args.push('--strip-list='+ agmt_strip); + } + } + + if ( !($("#agmt-schedule-checkbox").is(":checked")) ){ + agmt_start = $("#agmt-start-time").val().replace(':',''); + agmt_end = $("#agmt-end-time").val().replace(':',''); + + if (agmt_start == agmt_end) { + popup_msg("Error", "The replication start and end times can not behte same"); + return; + } + + // build the days + var agmt_days = ""; + if ( $("#schedule-sun").is(":checked") ){ + agmt_days = "0"; + } + if ( $("#schedule-mon").is(":checked") ){ + agmt_days += "1"; + } + if ( $("#schedule-tue").is(":checked") ){ + agmt_days += "2"; + } + if ( $("#schedule-wed").is(":checked") ){ + agmt_days += "3"; + } + if ( $("#schedule-thu").is(":checked") ){ + agmt_days += "4"; + } + if ( $("#schedule-fri").is(":checked") ){ + agmt_days += "5"; + } + if ( $("#schedule-sat").is(":checked") ){ + agmt_days += "6"; + } + if (agmt_days == "" ){ + popup_msg("Error", "You must set at least one day in the schedule to perform replication"); + return; + } + // Set final value + agmt_schedule = agmt_start + "-" + agmt_end + " " + agmt_days; + + if (!editing ){ + cmd_args.push('--schedule=' + agmt_schedule); + } else { + if ( !('nsds5replicaupdateschedule' in repl_agmt_values) || + agmt_schedule != repl_agmt_values['nsds5replicaupdateschedule'] ) + { + cmd_args.push('--schedule=' + agmt_schedule); + } + } + } else { + // if "sync all the time" is checked, might need to remove the schedule attribute + if ('nsds5replicaupdateschedule' in repl_agmt_values) { + cmd_args.push('--schedule='); + } + } + if (agmt_init == "online-init") { + init_replica = true; + } + if ( agmt_name == "") { + $("#agmt-cn").css("border-color", "red"); + param_err = true; + } else { + $("#agmt-cn").css("border-color", "initial"); + cmd_args.push('"' + agmt_name + '"'); + } + + // Create agreement in DS + if ( editing ) { + cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'set', '--suffix=' + suffix ]; + } else { + cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'create', '--suffix=' + suffix]; + } + cmd = cmd.concat(cmd_args); + log_cmd('#agmt-save (click)', 'Create/Set replication agreement', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + if (editing){ + popup_success('Successfully edited replication agreement'); + } else { + popup_success('Successfully created replication agreement'); + } + if (init_replica) { + // Launch popup stating initialization has begun + var init_cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'init', '--suffix=' + suffix, agmt_name ]; + log_cmd('#agmt-save (click)', 'Initialize agreement', init_cmd); + cockpit.spawn(init_cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function() { + get_and_set_repl_agmts(); + }).fail(function(data) { + popup_err("Failed to initialize replication agreement", data.message); + }); + } else { + get_and_set_repl_agmts(); + } + }).fail(function(data) { + if (editing) { + popup_err("Failed to edit replication agreement", data.message); + } else { + popup_err("Failed to create replication agreement", data.message); + } + }); + + // Done, close the form + $("#agmt-form").modal('toggle'); + clear_agmt_wizard(); + }); + + /* + * Initialize agreement + */ + $(document).on('click', '.agmt-init-btn', function(e) { + e.preventDefault(); + var suffix = $("#select-repl-agmt-suffix").val(); + var data = repl_agmt_table.row( $(this).parents('tr') ).data(); + var agmt_name = data[0]; + var row_idx = $(this).closest('tr').index(); + repl_agmt_table.cell({row: row_idx, column: 5}).data(progress_html).draw(); + + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'init', '--suffix=' + suffix, '"' + agmt_name + '"' ]; + log_cmd('.agmt-init-btn (click)', 'Initialize replication agreement', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + var init_idx = agmt_init_counter; + agmt_init_counter += 1; + agmt_init_intervals[init_idx] = setInterval( do_agmt_init, 2000, suffix, agmt_name, init_idx); + }).fail(function(data) { + get_and_set_repl_agmts(); + popup_err("Failed to initialize agreement", data.message); + }); + }); + + $(document).on('click', '.winsync-agmt-init-btn', function(e) { + e.preventDefault(); + var suffix = $("#select-repl-winsync-suffix").val(); + var data = repl_winsync_agmt_table.row( $(this).parents('tr') ).data(); + var agmt_name = data[0]; + var row_idx = $(this).closest('tr').index(); + repl_winsync_agmt_table.cell({row: row_idx, column: 5}).data(progress_html).draw(); + + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-winsync-agmt', 'init', '--suffix=' + suffix, '"' + agmt_name + '"' ]; + log_cmd('.winsync-agmt-init-btn (click)', 'Initialize replication winsync agreement', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + var init_idx = agmt_init_counter; + agmt_init_counter += 1; + agmt_init_intervals[init_idx] = setInterval( do_winsync_agmt_init, 2000, suffix, agmt_name, init_idx); + }).fail(function(data) { + get_and_set_repl_winsync_agmts(); + popup_err("Failed to initialize winsync agreement", data.message); + }); + }); + + + /* Store the repl dn from the table when opening the mgr delete confirmation modal */ + $(document).on('click', '.remove-repl-mgr', function(e) { + e.preventDefault(); + var mgr_row = $(this).parent().parent(); + var suffix = $("#select-repl-cfg-suffix").val(); + var mgr_dn = mgr_row.children("td:nth-child(1)"); + popup_confirm("Are you sure you want to delete Replication Manager: " + mgr_dn.text() + "", "Confirmation", function (yes) { + if (yes) { + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication' ,'set', + '--repl-del-bind-dn=' + mgr_dn.text(), '--suffix=' + suffix]; + log_cmd('.remove-repl-mgr (click)', 'Remove replication manager ', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + /* Remove the manager entry */ + var del_cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','replication', + 'delete-manager', "--name=" + mgr_dn.text()]; + log_cmd('.remove-repl-mgr(click)', 'Delete replication manager entry', del_cmd); + cockpit.spawn(del_cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + popup_success('Successfully removed replication manager'); + get_and_set_repl_config(); + }); + }).fail(function(data) { + get_and_set_repl_config(); + popup_err("Failed to remove replication manager", data.message); + }); + } + }); + }); + + /* + * Delete repl agreement + */ + $(document).on('click', '.agmt-del-btn', function(e) { + e.preventDefault(); + var data = repl_agmt_table.row( $(this).parents('tr') ).data(); + var del_agmt_name = data[0]; + var agmt_row = $(this); + popup_confirm("Are you sure you want to delete replication agreement: " + del_agmt_name + "", "Confirmation", function (yes) { + if (yes) { + var suffix = $("#select-repl-agmt-suffix").val(); + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'delete', '--suffix=' + suffix, '"' + del_agmt_name + '"']; + log_cmd('.agmt-del-btn (click)', 'Delete replication agreement', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + popup_success('Successfully removed replication agreement'); + // Update table + repl_agmt_table.row( agmt_row.parents('tr') ).remove().draw( false ); + }).fail(function(data) { + get_and_set_repl_config(); + popup_err("Failed to remove replication agreement", data.message); + }); + } + }); + }); + + $(document).on('click', '.winsync-agmt-del-btn', function(e) { + e.preventDefault(); + var data = repl_winsync_agmt_table.row( $(this).parents('tr') ).data(); + var del_agmt_name = data[0]; + var agmt_row = $(this); + popup_confirm("Are you sure you want to delete replication agreement: " + del_agmt_name + "", "Confirmation", function (yes) { + if (yes) { + var suffix = $("#select-repl-agmt-suffix").val(); + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-winsync-agmt', 'delete', '--suffix=' + suffix, '"' + del_agmt_name + '"']; + log_cmd('.winsync-agmt-del-btn (click)', 'Delete replication winsync agreement', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + popup_success('Successfully removed replication winsync agreement'); + // Update table + repl_winsync_agmt_table.row( agmt_row.parents('tr') ).remove().draw( false ); + }).fail(function(data) { + get_and_set_repl_config(); + popup_err("Failed to remove replication winsync agreement", data.message); + }); + } + }); + }); + + /* + * Edit Agreement + */ + $(document).on('click', '.agmt-edit-btn', function(e) { + e.preventDefault(); + clear_agmt_wizard(); + var suffix = $("#select-repl-agmt-suffix").val(); + var data = repl_agmt_table.row( $(this).parents('tr') ).data(); + var edit_agmt_name = data[0]; + // Set agreement form values + $("#agmt-wizard-title").html("Edit Replication Agreement"); + + // Hide init dropdown + $("#init-agmt-dropdown").hide(); + + // Get agreement from DS and populate form + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'get', '--suffix=' + suffix, '"' + edit_agmt_name + '"']; + log_cmd('.agmt-edit-btn (click)', 'Edit replication agreement', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + var agmt_obj = JSON.parse(data); + var frac_attrs = ""; + var frac_tot_attrs = ""; + var strip_attrs = ""; + + $("#agmt-cn").val(edit_agmt_name); + for (var attr in agmt_obj['attrs']) { + var val = agmt_obj['attrs'][attr][0]; + attr = attr.toLowerCase(); + $("#" + attr).val(val); + repl_agmt_values[attr] = val; + } + + // Fill Password Confirm Input + if ( 'nsds5replicacredentials' in agmt_obj['attrs'] ){ + $("#nsds5replicacredentials-confirm").val(agmt_obj['attrs']["nsds5replicacredentials"][0]); + } + + // Transport info + val = agmt_obj['attrs']["nsds5replicatransportinfo"][0].toLowerCase(); + if (val == "ldap"){ + $("#nsds5replicatransportinfo").val("LDAP"); + } else if (val == "ldaps"){ + $("#nsds5replicatransportinfo").val("LDAPS"); + } else if (val == "starttls" || val == "tls"){ + $("#nsds5replicatransportinfo").val("StartTLS"); + } + + // Bind Method + val = agmt_obj['attrs']["nsds5replicabindmethod"][0].toLowerCase(); + if (val == "simple"){ + $("#nsds5replicabindmethod").val("SIMPLE"); + } else if (val == "sasl/digest-md5"){ + $("#nsds5replicabindmethod").val("SASL/DIGEST-MD5"); + } else if (val == "sasl/gssapi"){ + $("#nsds5replicabindmethod").val("SASL/GSSAPI"); + } else if (val == "sslclientauth"){ + $("#nsds5replicatransportinfo").val("SSLCLIENTAUTH"); + } + + // Load fractional lists + if ( 'nsds5replicatedattributelist' in agmt_obj['attrs'] ){ + frac_attrs = agmt_obj['attrs']['nsds5replicatedattributelist'][0]; + frac_attrs = frac_attrs.replace(frac_prefix, "").split(" "); + for(var i = 0; i < frac_attrs.length; i++) { + var opt = frac_attrs[i]; + if (opt != "") { + var option = $('').attr("value", opt).text(opt); + $("#frac-exclude-list").append(option); + } + } + } + if ( 'nsds5replicatedattributelisttotal' in agmt_obj['attrs'] ){ + frac_tot_attrs = agmt_obj['attrs']['nsds5replicatedattributelisttotal'][0]; + frac_tot_attrs = frac_tot_attrs.replace(frac_prefix, "").split(" "); + for(var i = 0; i < frac_tot_attrs.length; i++) { + var opt = frac_tot_attrs[i]; + if (opt != "") { + var option = $('').attr("value", opt).text(opt); + $("#frac-exclude-tot-list").append(option); + } + } + } + if ( 'nsds5replicastripattrs' in agmt_obj['attrs'] ){ + strip_attrs = agmt_obj['attrs']['nsds5replicastripattrs'][0]; + strip_attrs = strip_attrs.split(" "); + for(var i = 0; i < strip_attrs.length; i++) { + var opt = strip_attrs[i]; + if (opt != "") { + var option = $('').attr("value", opt).text(opt); + $("#frac-strip-list").append(option); + } + } + } + + // Set schedule + if ( 'nsds5replicaupdateschedule' in agmt_obj['attrs'] ){ + var val = agmt_obj['attrs']['nsds5replicaupdateschedule'][0]; + var parts = val.split(" "); + var days = parts[1]; + var times = parts[0].split("-"); + var start_time = times[0].substring(0,2) + ":" + times[0].substring(2,4); + var end_time = times[1].substring(0,2) + ":" + times[1].substring(2,4); + + $("#agmt-schedule-checkbox").prop('checked', false); + $('#agmt-schedule-panel *').attr('disabled', false); + $("#schedule-settings").show(); + + $("#agmt-start-time").val(start_time); + $("#agmt-end-time").val(end_time); + if ( days.indexOf('0') != -1){ // Sunday + $("#schedule-sun").prop('checked', true); + } + if ( days.indexOf('1') != -1){ // Monday + $("#schedule-mon").prop('checked', true); + } + if ( days.indexOf('2') != -1){ // Tuesday + $("#schedule-tue").prop('checked', true); + } + if ( days.indexOf('3') != -1){ // Wednesday + $("#schedule-wed").prop('checked', true); + } + if ( days.indexOf('4') != -1){ // Thursday + $("#schedule-thu").prop('checked', true); + } + if ( days.indexOf('5') != -1){ // Friday + $("#schedule-fri").prop('checked', true); + } + if ( days.indexOf('6') != -1){ // Saturday + $("#schedule-sat").prop('checked', true); + } + } + // Finally Open form + $("#agmt-form").modal('toggle'); + }).fail(function(data) { + popup_err("Failed to get replication agreement entry", data.message); + }); + }); + + /* + * Edit Winsync Agreement + */ + $(document).on('click', '.winsync-agmt-edit-btn', function(e) { + e.preventDefault(); + clear_winsync_agmt_wizard(); + var suffix = $("#select-repl-winsync-suffix").val(); + var data = repl_winsync_agmt_table.row( $(this).parents('tr') ).data(); + var edit_agmt_name = data[0]; + + // Get agreement from DS and populate form + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-winsync-agmt', 'get', '--suffix=' + suffix, '"' + edit_agmt_name + '"']; + log_cmd('.winsync-agmt-edit-btn (click)', 'Get replication winsync agreement', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + var agmt_obj = JSON.parse(data); + + // Set agreement form values + $("#winsync-agmt-wizard-title").html("Edit Winsync Agreement"); + // Hide init dropdown + $("#winsync-init-chbx").hide(); + $("#winsync-agmt-cn").val(edit_agmt_name); + for (var attr in agmt_obj['attrs']) { + var val = agmt_obj['attrs'][attr][0]; + attr = attr.toLowerCase(); + $("#winsync-" + attr).val(val); + if (val == "on") { + $("#winsync-" + attr + "-checkbox").prop('checked', true); + } else if (val == "off") { + $("#winsync-" + attr + "-checkbox").prop('checked', false); + } + repl_winsync_agmt_values[attr] = val; + } + + // Fill Password Confirm Input + if ( 'nsds5replicacredentials' in agmt_obj['attrs'] ){ + $("#winsync-nsds5replicacredentials-confirm").val(agmt_obj['attrs']["nsds5replicacredentials"][0]); + } + + // Transport info + val = agmt_obj['attrs']["nsds5replicatransportinfo"][0].toLowerCase(); + if (val == "ldap"){ + $("#winsync-nsds5replicatransportinfo").val("LDAP"); + } else if (val == "ldaps"){ + $("#winsync-nsds5replicatransportinfo").val("LDAPS"); + } else if (val == "starttls" || val == "tls"){ + $("#winsync-nsds5replicatransportinfo").val("StartTLS"); + } + + // Finally open the form + $("#winsync-agmt-form").modal('toggle'); + }).fail(function(data) { + popup_err("Failed to load replication winsync agreement entry", data.message); + }); + }); + + + // Handle disabling/enabling of agmt schedule panel + $('#agmt-schedule-panel *').attr('disabled', true); /// Disabled by default + $("#agmt-schedule-checkbox").change(function() { + if(this.checked) { + $('#agmt-schedule-panel *').attr('disabled', true); + $("#schedule-settings").hide(); + } else { + $('#agmt-schedule-panel *').attr('disabled', false); + $("#schedule-settings").show(); + } + }); + + // Based on the connection type change the agmt-auth options + $("#nsds5replicatransportinfo").change(function() { + var ldap_opts = {"Simple": "Simple", + "SASL/DIGEST-MD5": "SASL/DIGEST-MD5", + "SASL/GSSAPI": "SASL/GSSAPI"}; + var ldaps_opts = {"Simple": "Simple", + "SSL Client Authentication": "SSL Client Authentication", + "SASL/DIGEST-MD5": "SASL/DIGEST-MD5"}; + var $auth = $("#nsds5replicabindmethod"); + $auth.empty(); + var conn = $('#nsds5replicatransportinfo').val(); + if (conn == "LDAP"){ + $.each(ldap_opts, function(key, value) { + $auth.append($("").attr("value", value).text(key)); + }); + } else { + // TLS options + $.each(ldaps_opts, function(key, value) { + $auth.append($("").attr("value", value).text(key)); + }); + } + $("#nsds5replicabinddn").prop('disabled', false); + $("#nsds5replicacredentials").prop('disabled', false); + $("#nsds5replicacredentials-confirm").prop('disabled', false); + }); + + // Check for auth changes and disable/enable bind DN & password + $("#nsds5replicabindmethod").change(function() { + var authtype = $('#nsds5replicabindmethod').val(); + if (authtype == "SSL Client Authentication") { + $("#nsds5replicabinddn").prop('disabled', true); + $("#nsds5replicacredentials").prop('disabled', true); + $("#nsds5replicacredentials-confirm").prop('disabled', true); + } else { + $("#nsds5replicabinddn").prop('disabled', false); + $("#nsds5replicacredentials").prop('disabled', false); + $("#nsds5replicacredentials-confirm").prop('disabled', false); + } + }); + + // Create time picker for agmt schedule (start end times)) + $('input.timepicker').timepicker({ + 'timeFormat': 'H:i', + 'step': 15 + }); + + // Accordion opening/closings + + $(".ds-accordion-panel").css('display','none'); + + $("#repl-config-accordion").on("click", function() { + this.classList.toggle("active"); + var panel = this.nextElementSibling; + if (panel.style.display === "block") { + var show = "► Show Advanced Settings "; + $(this).html(show); + panel.style.display = "none"; + $(this).blur(); + } else { + var hide = "▼ Hide Advanced Settings "; + $(this).html(hide); + panel.style.display = "block"; + $(this).blur(); + } + }); + + $("#frac-accordion").on("click", function() { + this.classList.toggle("active"); + var panel = this.nextElementSibling; + if (panel.style.display === "block") { + var show = "► Show Fractional Settings "; + $(this).html(show); + panel.style.display = "none"; + $(this).blur(); + } else { + var hide = "▼ Hide Fractional Settings "; + $(this).html(hide); + panel.style.display = "block"; + $(this).blur(); + } + }); + + $("#schedule-accordion").on("click", function() { + this.classList.toggle("active"); + var panel = this.nextElementSibling; + if (panel.style.display === "block") { + var show = "► Show Schedule Settings "; + $(this).html(show); + panel.style.display = "none"; + $(this).blur(); + } else { + var hide = "▼ Hide Schedule Settings "; + $(this).html(hide); + panel.style.display = "block"; + $(this).blur(); + } + }); + + /* + * Handle the repl agmt wizard select lists + */ + + /* + * Set the "select"'s list-id in a hidden field on the select attribute form + * so we know what list to update after the selection + */ + + $(".ds-fractional-btn").on('click', function() { + // reset the list + $("#select-attr-list").prop('selectedIndex',-1); + }); + $("#frac-list-add-btn").on('click', function () { + $("#attr-form-id").val("frac-exclude-list"); + }); + $("#frac-total-list-add-btn").on('click', function () { + $("#attr-form-id").val("frac-exclude-tot-list"); + }); + $("#frac-strip-list-add-btn").on('click', function () { + $("#attr-form-id").val("frac-strip-list"); + }); + + // Handle the attribute removal from the lists + $("#frac-list-remove-btn").on("click", function () { + $("#frac-exclude-list").find('option:selected').remove(); + }); + $("#frac-total-list-remove-btn").on("click", function () { + $("#frac-exclude-tot-list").find('option:selected').remove(); + }); + $("#frac-strip-list-remove-btn").on("click", function () { + $("#frac-strip-list").find('option:selected').remove(); + }); + + // Update agmt form attribute selection lists + $("#select-attr-save").on("click", function () { + // Get the id from the hidden input filed and append the attribute to it + var list_id = $("#attr-form-id").val(); + var add_attrs = $("#select-attr-list").find('option:selected'); + if (add_attrs && add_attrs != '' && add_attrs.length > 0) { + for (var i = 0; i < add_attrs.length; i++) { + if ( $('#' + list_id + ' option[value="' + add_attrs[i].text + '"]').val() === undefined) { + $('#' + list_id).append($("').attr("value", oc_name).text(oc_name); + $("#oc-parent").append(option); + } + $("#save-oc-spinner").hide(); + popup_success("The objectClass was saved in DS"); + $("#add-edit-oc-form").modal('toggle'); + }). + fail(function(data) { + $("#save-oc-spinner").hide(); + popup_err("Error", "Failed to save the objectClass\n" + data.message); + $("#add-edit-oc-form").modal('toggle'); + }); + }); + + // Required Attributes + $("#oc-must-add-button").on("click", function () { + var add_attrs = $("#schema-list").val(); + if (add_attrs && add_attrs != '' && add_attrs.length > 0) { + for (var i = 0; i < add_attrs.length; i++) { + if ( $('#oc-required-list option[value="' + add_attrs[i] + '"]').val() === undefined) { + $('#oc-required-list').append($("').attr("value", attr_name).text(attr_name); + $("#schema-list").append(option); + } + $("#save-attr-spinner").hide(); + popup_success("The attribute was saved in DS"); + $("#add-edit-attr-form").modal('toggle'); + }). + fail(function(data) { + $("#save-attr-spinner").hide(); + popup_err("Error", "Failed to save the attribute\n" + data.message); + $("#add-edit-attr-form").modal('toggle'); + }); + }); + + function load_attr_form(element) { + clear_attr_form(); + var data = schema_at_table.row(element.parents('tr') ).data(); + var edit_attr_name = data[0]; + var edit_attr_oid = data[1]; + var edit_attr_syntax = $.parseHTML(data[2])[0].title; + var edit_attr_multivalued = data[3]; + var edit_attr_eq_mr = data[4]; + var edit_attr_order_mr = data[5]; + var edit_attr_sub_mr = data[6]; + var edit_attr_desc = data[8]; + var edit_attr_aliases = data[9]; + var edit_attr_x_origin = data[10]; + var edit_attr_usage = data[11]; + var edit_attr_no_user_mod = data[12]; + var edit_attr_parent = data[13]; + if (edit_attr_eq_mr) { + edit_attr_eq_mr = data[4]; + } + if (edit_attr_order_mr) { + edit_attr_order_mr = data[5]; + } + if (edit_attr_sub_mr) { + edit_attr_sub_mr = data[6]; + } + + $("#add-edit-attr-header").html('Edit Attribute: ' + edit_attr_name); + $("#attr-name").val(edit_attr_name); + $("#attr-name").attr('disabled', true); + $("#attr-oid").val(edit_attr_oid); + $("#attr-usage")[0].value = edit_attr_usage; + $("#attr-parent")[0].value = edit_attr_parent; + $("#attr-desc").val(edit_attr_desc); + $("#attr-x-origin").val(edit_attr_x_origin); + if (edit_attr_aliases) { + $("#attr-alias").val(edit_attr_aliases.join(" ")); + } + $("#attr-syntax").val(edit_attr_syntax); + $("#attr-multivalued").prop('checked', false); + if (edit_attr_multivalued == "yes") { + $("#attr-multivalued").prop('checked', true); + } + $("#attr-no-user-mod").prop('checked', false); + if (edit_attr_no_user_mod) { + $("#attr-no-user-mod").prop('checked', true); + } + $("#save-attr-spinner").show(); + $("#attr-eq-mr-select")[0].value = edit_attr_eq_mr; + $("#attr-order-mr-select")[0].value = edit_attr_order_mr; + $("#attr-sub-mr-select")[0].value = edit_attr_sub_mr; + $("#save-attr-spinner").hide(); + + $("#add-edit-attr-form").modal('toggle'); + } + + $(document).on('click', '.attr-view-btn', function(e) { + e.preventDefault(); + load_attr_form($(this)); + $("#save-attr-button").attr('title', 'Only user-defined attributes can be modified'); + $("#save-attr-button").attr('disabled', true); + }); + + $(document).on('click', '.attr-edit-btn', function(e) { + e.preventDefault(); + load_attr_form($(this)); + }); + + $(document).on('click', '.attr-del-btn', function(e) { + e.preventDefault(); + var data = schema_at_table.row( $(this).parents('tr') ).data(); + var del_attr_name = data[0]; + var at_row = $(this); + popup_confirm("Are you sure you want to delete attribute: " + del_attr_name + "", "Confirmation", function (yes) { + if (yes) { + var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket', 'schema', 'attributetypes', 'remove', del_attr_name]; + log_cmd('.attr-del-btn (click)', 'Remove attribute', cmd); + cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) { + popup_success("Attribute was successfully removed!"); + schema_at_table.row( at_row.parents('tr') ).remove().draw( false ); + $("#schema-list option[value='" + del_attr_name + "']").remove(); + }).fail(function(data) { + popup_err("Attribute removal error", del_attr_name + " removal has failed: " + data.message); + }); + } + }); + }); + + function load_oc_form(element) { + clear_oc_form(); + var data = schema_oc_table.row(element.parents('tr') ).data(); + var edit_oc_name = data[0]; + var edit_oc_oid = data[1]; + var edit_oc_parent = data[2]; + var edit_oc_required = data[3].split(" "); + var edit_oc_allowed = data[4].split(" "); + var edit_oc_x_origin = data[6]; + var edit_oc_kind = data[7]; + var edit_oc_desc = data[8]; + if (edit_oc_parent) { + edit_oc_parent = data[2]; + } + + $("#save-oc-spinner").show(); + $("#add-edit-oc-header").html('Edit Objectclass: ' + edit_oc_name); + $("#oc-name").attr('disabled', true); + $("#oc-name").val(edit_oc_name); + $("#oc-oid").val(edit_oc_oid); + $("#oc-kind")[0].value = edit_oc_kind; + $("#oc-desc").val(edit_oc_desc); + $("#oc-x-origin").val(edit_oc_x_origin); + $("#oc-parent")[0].value = edit_oc_parent; + $.each(edit_oc_required, function (i, item) { + if (item) { + $("#oc-required-list").append($('