[389-ds-base] branch 389-ds-base-1.4.0 updated: Bump version to 1.4.0.21
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.0
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.0 by this push:
new 9290997 Bump version to 1.4.0.21
9290997 is described below
commit 92909976b6b741a8932c8b6db42fa9ba660c1520
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Thu Jan 31 09:46:11 2019 -0500
Bump version to 1.4.0.21
---
VERSION.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/VERSION.sh b/VERSION.sh
index 88330ee..1b43006 100644
--- a/VERSION.sh
+++ b/VERSION.sh
@@ -10,7 +10,7 @@ vendor="389 Project"
# PACKAGE_VERSION is constructed from these
VERSION_MAJOR=1
VERSION_MINOR=4
-VERSION_MAINT=0.20
+VERSION_MAINT=0.21
# NOTE: VERSION_PREREL is automatically set for builds made out of a git tree
VERSION_PREREL=
VERSION_DATE=$(date -u +%Y%m%d)
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 8 months
[389-ds-base] branch 389-ds-base-1.4.0 updated: Issue 50041 - CLI and WebUI - Add memberOf plugin functionality
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.0
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.0 by this push:
new 0be0149 Issue 50041 - CLI and WebUI - Add memberOf plugin functionality
0be0149 is described below
commit 0be01490e171aa1aacba57616940f22b20481e7d
Author: Simon Pichugin <spichugi(a)redhat.com>
AuthorDate: Wed Jan 9 21:07:55 2019 +0100
Issue 50041 - CLI and WebUI - Add memberOf plugin functionality
Description: Add the main functionality to memberOf plugin tab.
Increase the eslint max line length from 80 to 100.
Rework plugin properties to be more compact.
Eslint webpack config. Add react-bootstrap-typeahead for
multivalued attributes. Fix the word 'successfully' typos.
https://pagure.io/389-ds-base/issue/50041
Reviewed by: mreynolds, wibrown (Thanks!)
---
src/cockpit/389-console/.eslintrc.json | 3 +-
src/cockpit/389-console/package.json | 7 +-
src/cockpit/389-console/src/css/ds.css | 16 +-
src/cockpit/389-console/src/index.html | 1 +
src/cockpit/389-console/src/lib/customCollapse.jsx | 1 -
.../389-console/src/lib/plugins/memberOf.jsx | 955 ++++++++++++++++++++-
.../src/lib/plugins/pluginBasicConfig.jsx | 227 ++---
.../389-console/src/lib/plugins/pluginModal.jsx | 165 ++--
src/cockpit/389-console/src/plugins.jsx | 153 +++-
src/cockpit/389-console/src/static/Typeahead.css | 256 ++++++
src/cockpit/389-console/webpack.config.js | 72 +-
src/lib389/lib389/_mapped_object.py | 31 +-
src/lib389/lib389/cli_conf/__init__.py | 73 +-
src/lib389/lib389/cli_conf/backend.py | 6 +-
src/lib389/lib389/cli_conf/plugin.py | 44 +-
src/lib389/lib389/cli_conf/plugins/memberof.py | 356 +++-----
src/lib389/lib389/cli_ctl/instance.py | 5 +-
src/lib389/lib389/cli_idm/__init__.py | 4 +-
src/lib389/lib389/clitools/ds_setup | 3 +-
src/lib389/lib389/replica.py | 20 +-
src/lib389/lib389/tests/cli/conf_backend_test.py | 12 +-
src/lib389/lib389/tests/cli/conf_chaining_test.py | 4 +-
src/lib389/lib389/tests/cli/idm_group_test.py | 7 +-
src/lib389/lib389/tests/cli/idm_user_test.py | 7 +-
24 files changed, 1837 insertions(+), 591 deletions(-)
diff --git a/src/cockpit/389-console/.eslintrc.json b/src/cockpit/389-console/.eslintrc.json
index 11a82c8..ee0a235 100644
--- a/src/cockpit/389-console/.eslintrc.json
+++ b/src/cockpit/389-console/.eslintrc.json
@@ -44,7 +44,8 @@
"eqeqeq": "off",
"import/no-webpack-loader-syntax": "off",
"object-property-newline": "off",
- "react/jsx-no-bind": "off"
+ "react/jsx-no-bind": "off",
+ "max-len": ["error", { "code": 100 }]
},
"globals": {
"require": false,
diff --git a/src/cockpit/389-console/package.json b/src/cockpit/389-console/package.json
index 054a373..0699691 100644
--- a/src/cockpit/389-console/package.json
+++ b/src/cockpit/389-console/package.json
@@ -14,13 +14,13 @@
"@babel/core": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
+ "ajv": "^6.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",
- "style-loader": "^0.23.1",
"eslint": "^5.4.0",
"eslint-config-standard": "^11.0.0",
"eslint-config-standard-react": "^6.0.0",
@@ -34,17 +34,20 @@
"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",
+ "style-loader": "^0.23.1",
"webpack": "^4.17.1",
"webpack-cli": "^3.1.0"
},
"dependencies": {
"patternfly": "3.58.0",
"patternfly-react": "2.24.5",
+ "bootstrap": "4.2.1",
+ "node-sass": "4.11.0",
"react-bootstrap": "0.32.4",
+ "react-bootstrap-typeahead": "3.2.4",
"react": "16.6.1",
"react-dom": "16.6.1",
"prop-types": "15.6.2",
diff --git a/src/cockpit/389-console/src/css/ds.css b/src/cockpit/389-console/src/css/ds.css
index d38ff55..8e9ba21 100644
--- a/src/cockpit/389-console/src/css/ds.css
+++ b/src/cockpit/389-console/src/css/ds.css
@@ -1310,7 +1310,7 @@ option {
.ds-td {
padding-left: 10px !important;
padding-top: 8px !important;
- padding-bottom: 0px ~important;
+ padding-bottom: 0px !important;
valign: middle !important;
}
@@ -1454,6 +1454,11 @@ tbody:nth-child(even) {
bottom: 10px;
}
+.ds-plugin-button {
+ margin-right: 5px;
+ margin-left: 5px;
+}
+
.ds-plugin-spinner {
margin-top: 20px;
margin-bottom: 10px;
@@ -1494,3 +1499,12 @@ tbody:nth-child(even) {
.control-label {
text-align: left !important;
}
+
+.rbt-token {
+ background-color: #ededed;
+ color: #363636;
+}
+
+.rbt-input-multi {
+ height: auto !important;
+}
diff --git a/src/cockpit/389-console/src/index.html b/src/cockpit/389-console/src/index.html
index 6b3f213..b23a722 100644
--- a/src/cockpit/389-console/src/index.html
+++ b/src/cockpit/389-console/src/index.html
@@ -30,6 +30,7 @@
<link href="static/jquery.timepicker.min.css" type="text/css" rel="stylesheet">
<link href="static/style.min.css" rel="stylesheet">
<link href="static/patternfly-additions.css" rel="stylesheet" type="text/css">
+ <link href="static/Typeahead.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="../base1/patternfly.css">
<link href="css/ds.css" type="text/css" rel="stylesheet">
</head>
diff --git a/src/cockpit/389-console/src/lib/customCollapse.jsx b/src/cockpit/389-console/src/lib/customCollapse.jsx
index 71ea0f5..b992982 100644
--- a/src/cockpit/389-console/src/lib/customCollapse.jsx
+++ b/src/cockpit/389-console/src/lib/customCollapse.jsx
@@ -26,7 +26,6 @@ class CustomCollapse extends React.Component {
>
<Icon
type="fa"
- size="1,5x"
name={open ? "caret-down" : "caret-right"}
/>{" "}
{open ? textOpened : textClosed}
diff --git a/src/cockpit/389-console/src/lib/plugins/memberOf.jsx b/src/cockpit/389-console/src/lib/plugins/memberOf.jsx
index 33a2091..51ecd59 100644
--- a/src/cockpit/389-console/src/lib/plugins/memberOf.jsx
+++ b/src/cockpit/389-console/src/lib/plugins/memberOf.jsx
@@ -1,24 +1,975 @@
+import cockpit from "cockpit";
import React from "react";
-import { noop } from "patternfly-react";
+import {
+ Icon,
+ Modal,
+ Button,
+ Row,
+ Col,
+ Form,
+ noop,
+ FormGroup,
+ FormControl,
+ Checkbox,
+ ControlLabel
+} from "patternfly-react";
+import { Typeahead } from "react-bootstrap-typeahead";
import PropTypes from "prop-types";
import PluginBasicConfig from "./pluginBasicConfig.jsx";
+import { log_cmd } from "../tools.jsx";
import "../../css/ds.css";
class MemberOf extends React.Component {
+ componentWillMount(prevProps) {
+ this.updateFields();
+ }
+
+ componentDidUpdate(prevProps) {
+ if (this.props.rows !== prevProps.rows) {
+ this.updateFields();
+ }
+ }
+
+ constructor(props) {
+ super(props);
+
+ this.updateFields = this.updateFields.bind(this);
+ this.handleFieldChange = this.handleFieldChange.bind(this);
+ this.handleCheckboxChange = this.handleCheckboxChange.bind(this);
+ this.openModal = this.openModal.bind(this);
+ this.closeModal = this.closeModal.bind(this);
+ this.addConfig = this.addConfig.bind(this);
+ this.editConfig = this.editConfig.bind(this);
+ this.deleteConfig = this.deleteConfig.bind(this);
+ this.cmdOperation = this.cmdOperation.bind(this);
+ this.runFixup = this.runFixup.bind(this);
+ this.toggleFixupModal = this.toggleFixupModal.bind(this);
+
+ this.state = {
+ memberOfAttr: [],
+ memberOfGroupAttr: [],
+ memberOfEntryScope: "",
+ memberOfEntryScopeExcludeSubtree: "",
+ memberOfAutoAddOC: "",
+ memberOfAllBackends: false,
+ memberOfSkipNested: false,
+ memberOfConfigEntry: "",
+ configEntryModalShow: false,
+ fixupModalShow: false,
+
+ configDN: "",
+ configAttr: [],
+ configGroupAttr: [],
+ configEntryScope: "",
+ configEntryScopeExcludeSubtree: "",
+ configAutoAddOC: "",
+ configAllBackends: false,
+ configSkipNested: false,
+ newEntry: true,
+
+ fixupDN: "",
+ fixupFilter: ""
+ };
+ }
+
+ toggleFixupModal() {
+ this.setState(prevState => ({
+ fixupModalShow: !prevState.fixupModalShow,
+ fixupDN: "",
+ fixupFilter: ""
+ }));
+ }
+
+ runFixup() {
+ if (!this.state.fixupDN) {
+ this.props.addNotification("warning", "Fixup DN is required.");
+ } else {
+ let cmd = [
+ "dsconf",
+ "-j",
+ "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket",
+ "plugin",
+ "memberof",
+ "fixup",
+ this.state.fixupDN
+ ];
+
+ if (this.state.fixupFilter) {
+ cmd = [...cmd, "--filter", this.state.fixupFilter];
+ }
+
+ this.props.toggleLoadingHandler();
+ log_cmd("runFixup", "Run fixup MemberOf Plugin ", cmd);
+ cockpit
+ .spawn(cmd, {
+ superuser: true,
+ err: "message"
+ })
+ .done(content => {
+ this.props.addNotification(
+ "success",
+ `Fixup task for ${this.state.fixupDN} was successfull`
+ );
+ this.props.toggleLoadingHandler();
+ this.setState({
+ fixupModalShow: false
+ });
+ })
+ .fail(err => {
+ this.props.addNotification(
+ "error",
+ `Fixup task for ${this.state.fixupDN} has failed ${err}`
+ );
+ this.props.toggleLoadingHandler();
+ this.setState({
+ fixupModalShow: false
+ });
+ });
+ }
+ }
+
+ openModal() {
+ if (!this.state.memberOfConfigEntry) {
+ this.setState({
+ configEntryModalShow: true,
+ newEntry: true,
+ configDN: "",
+ configAttr: [],
+ configGroupAttr: [],
+ configEntryScope: "",
+ configEntryScopeExcludeSubtree: "",
+ configAutoAddOC: "",
+ configAllBackends: false,
+ configSkipNested: false
+ });
+ } else {
+ let configAttrObjectList = [];
+ let configGroupAttrObjectList = [];
+ let cmd = [
+ "dsconf",
+ "-j",
+ "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket",
+ "plugin",
+ "memberof",
+ "config-entry",
+ "show",
+ this.state.memberOfConfigEntry
+ ];
+
+ this.props.toggleLoadingHandler();
+ log_cmd("openMemberOfModal", "Fetch the MemberOf Plugin config entry", cmd);
+ cockpit
+ .spawn(cmd, {
+ superuser: true,
+ err: "message"
+ })
+ .done(content => {
+ let configEntry = JSON.parse(content).attrs;
+ this.setState({
+ configEntryModalShow: true,
+ newEntry: false,
+ configDN: this.state.memberOfConfigEntry,
+ configAutoAddOC:
+ configEntry["memberofautoaddoc"] === undefined
+ ? ""
+ : configEntry["memberofautoaddoc"][0],
+ configAllBackends: !(
+ configEntry["memberofallbackends"] === undefined ||
+ configEntry["memberofallbackends"][0] == "off"
+ ),
+ configSkipNested: !(
+ configEntry["memberofskipnested"] === undefined ||
+ configEntry["memberofskipnested"][0] == "off"
+ ),
+ configConfigEntry:
+ configEntry["nsslapd-pluginConfigArea"] === undefined
+ ? ""
+ : configEntry["nsslapd-pluginConfigArea"][0],
+ configEntryScope:
+ configEntry["memberofentryscope"] === undefined
+ ? ""
+ : configEntry["memberofentryscope"][0],
+ configEntryScopeExcludeSubtree:
+ configEntry["memberofentryscopeexcludesubtree"] === undefined
+ ? ""
+ : configEntry["memberofentryscopeexcludesubtree"][0]
+ });
+ if (configEntry["memberofattr"] === undefined) {
+ this.setState({ configAttr: [] });
+ } else {
+ for (let value of configEntry["memberofattr"]) {
+ configAttrObjectList = [
+ ...configAttrObjectList,
+ { id: value, label: value }
+ ];
+ }
+ this.setState({ configAttr: configAttrObjectList });
+ }
+ if (configEntry["memberofgroupattr"] === undefined) {
+ this.setState({ configGroupAttr: [] });
+ } else {
+ for (let value of configEntry["memberofgroupattr"]) {
+ configGroupAttrObjectList = [
+ ...configGroupAttrObjectList,
+ { id: value, label: value }
+ ];
+ }
+ this.setState({ configGroupAttr: configGroupAttrObjectList });
+ this.props.toggleLoadingHandler();
+ }
+ })
+ .fail(_ => {
+ this.setState({
+ configEntryModalShow: true,
+ newEntry: true,
+ configDN: this.state.memberOfConfigEntry,
+ configAttr: [],
+ configGroupAttr: [],
+ configEntryScope: "",
+ configEntryScopeExcludeSubtree: "",
+ configAutoAddOC: "",
+ configAllBackends: false,
+ configSkipNested: false
+ });
+ this.props.toggleLoadingHandler();
+ });
+ }
+ }
+
+ closeModal() {
+ this.setState({ configEntryModalShow: false });
+ }
+
+ cmdOperation(action) {
+ const {
+ configDN,
+ configAttr,
+ configGroupAttr,
+ configEntryScope,
+ configEntryScopeExcludeSubtree,
+ configAutoAddOC,
+ configAllBackends,
+ configSkipNested
+ } = this.state;
+
+ if (configAttr.length == 0 || configGroupAttr.length == 0) {
+ this.props.addNotification(
+ "warning",
+ "Config Attribute and Group Attribute are required."
+ );
+ } else {
+ let cmd = [
+ "dsconf",
+ "-j",
+ "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket",
+ "plugin",
+ "memberof",
+ "config-entry",
+ action,
+ configDN,
+ "--scope",
+ configEntryScope || action == "add" ? configEntryScope : "delete",
+ "--exclude",
+ configEntryScopeExcludeSubtree || action == "add"
+ ? configEntryScopeExcludeSubtree
+ : "delete",
+ "--autoaddoc",
+ configAutoAddOC || action == "add" ? configAutoAddOC : "delete",
+ "--allbackends",
+ configAllBackends ? "on" : "off",
+ "--skipnested",
+ configSkipNested ? "on" : "off"
+ ];
+
+ // Delete attributes if the user set an empty value to the field
+ cmd = [...cmd, "--attr"];
+ if (configAttr.length != 0) {
+ for (let value of configAttr) {
+ cmd = [...cmd, value.label];
+ }
+ }
+ cmd = [...cmd, "--groupattr"];
+ if (configGroupAttr.length != 0) {
+ for (let value of configGroupAttr) {
+ cmd = [...cmd, value.label];
+ }
+ }
+
+ this.props.toggleLoadingHandler();
+ log_cmd("memberOfOperation", `Do the ${action} operation on the MemberOf Plugin`, cmd);
+ cockpit
+ .spawn(cmd, {
+ superuser: true,
+ err: "message"
+ })
+ .done(content => {
+ console.info("memberOfOperation", "Result", content);
+ this.props.addNotification(
+ "success",
+ `Config entry ${configDN} was successfully ${action}ed`
+ );
+ this.props.pluginListHandler();
+ this.closeModal();
+ this.props.toggleLoadingHandler();
+ })
+ .fail(err => {
+ this.props.addNotification(
+ "error",
+ `Error during the config entry ${action} operation - ${err}`
+ );
+ this.props.pluginListHandler();
+ this.closeModal();
+ this.props.toggleLoadingHandler();
+ });
+ }
+ }
+
+ deleteConfig() {
+ let cmd = [
+ "dsconf",
+ "-j",
+ "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket",
+ "plugin",
+ "memberof",
+ "config-entry",
+ "delete",
+ this.state.configDN
+ ];
+
+ this.props.toggleLoadingHandler();
+ log_cmd("deleteConfig", "Delete the MemberOf Plugin config entry", cmd);
+ cockpit
+ .spawn(cmd, {
+ superuser: true,
+ err: "message"
+ })
+ .done(content => {
+ console.info("deleteConfig", "Result", content);
+ this.props.addNotification(
+ "success",
+ `Config entry ${this.state.configDN} was successfully deleted`
+ );
+ this.props.pluginListHandler();
+ this.closeModal();
+ this.props.toggleLoadingHandler();
+ })
+ .fail(err => {
+ this.props.addNotification(
+ "error",
+ `Error during the config entry removal operation - ${err}`
+ );
+ this.props.pluginListHandler();
+ this.closeModal();
+ this.props.toggleLoadingHandler();
+ });
+ }
+
+ addConfig() {
+ this.cmdOperation("add");
+ }
+
+ editConfig() {
+ this.cmdOperation("edit");
+ }
+
+ handleCheckboxChange(e) {
+ this.setState({
+ [e.target.id]: e.target.checked
+ });
+ }
+
+ handleFieldChange(e) {
+ this.setState({
+ [e.target.id]: e.target.value
+ });
+ }
+
+ updateFields() {
+ let memberOfAttrObjectList = [];
+ let memberOfGroupAttrObjectList = [];
+
+ if (this.props.rows.length > 0) {
+ const pluginRow = this.props.rows.find(row => row.cn[0] === "MemberOf Plugin");
+
+ this.setState({
+ memberOfAutoAddOC:
+ pluginRow["memberofautoaddoc"] === undefined
+ ? ""
+ : pluginRow["memberofautoaddoc"][0],
+ memberOfAllBackends: !(
+ pluginRow["memberofallbackends"] === undefined ||
+ pluginRow["memberofallbackends"][0] == "off"
+ ),
+ memberOfSkipNested: !(
+ pluginRow["memberofskipnested"] === undefined ||
+ pluginRow["memberofskipnested"][0] == "off"
+ ),
+ memberOfConfigEntry:
+ pluginRow["nsslapd-pluginConfigArea"] === undefined
+ ? ""
+ : pluginRow["nsslapd-pluginConfigArea"][0],
+ memberOfEntryScope:
+ pluginRow["memberofentryscope"] === undefined
+ ? ""
+ : pluginRow["memberofentryscope"][0],
+ memberOfEntryScopeExcludeSubtree:
+ pluginRow["memberofentryscopeexcludesubtree"] === undefined
+ ? ""
+ : pluginRow["memberofentryscopeexcludesubtree"][0]
+ });
+ if (pluginRow["memberofattr"] === undefined) {
+ this.setState({ memberOfAttr: [] });
+ } else {
+ for (let value of pluginRow["memberofattr"]) {
+ memberOfAttrObjectList = [
+ ...memberOfAttrObjectList,
+ { id: value, label: value }
+ ];
+ }
+ this.setState({ memberOfAttr: memberOfAttrObjectList });
+ }
+ if (pluginRow["memberofgroupattr"] === undefined) {
+ this.setState({ memberOfGroupAttr: [] });
+ } else {
+ for (let value of pluginRow["memberofgroupattr"]) {
+ memberOfGroupAttrObjectList = [
+ ...memberOfGroupAttrObjectList,
+ { id: value, label: value }
+ ];
+ }
+ this.setState({ memberOfGroupAttr: memberOfGroupAttrObjectList });
+ }
+ }
+ }
+
render() {
+ const {
+ memberOfAttr,
+ memberOfGroupAttr,
+ memberOfEntryScope,
+ memberOfEntryScopeExcludeSubtree,
+ memberOfAutoAddOC,
+ memberOfAllBackends,
+ memberOfSkipNested,
+ memberOfConfigEntry,
+ configDN,
+ configEntryModalShow,
+ configAttr,
+ configGroupAttr,
+ configEntryScope,
+ configEntryScopeExcludeSubtree,
+ configAutoAddOC,
+ configAllBackends,
+ configSkipNested,
+ newEntry,
+ fixupModalShow,
+ fixupDN,
+ fixupFilter
+ } = this.state;
+
+ let specificPluginCMD = [
+ "dsconf",
+ "-j",
+ "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket",
+ "plugin",
+ "memberof",
+ "edit",
+ "--scope",
+ memberOfEntryScope || "delete",
+ "--exclude",
+ memberOfEntryScopeExcludeSubtree || "delete",
+ "--autoaddoc",
+ memberOfAutoAddOC || "delete",
+ "--config-entry",
+ memberOfConfigEntry || "delete",
+ "--allbackends",
+ memberOfAllBackends ? "on" : "off",
+ "--skipnested",
+ memberOfSkipNested ? "on" : "off"
+ ];
+
+ // Delete attributes if the user set an empty value to the field
+ specificPluginCMD = [...specificPluginCMD, "--attr"];
+ if (memberOfAttr.length != 0) {
+ for (let value of memberOfAttr) {
+ specificPluginCMD = [...specificPluginCMD, value.label];
+ }
+ } else {
+ specificPluginCMD = [...specificPluginCMD, "delete"];
+ }
+
+ specificPluginCMD = [...specificPluginCMD, "--groupattr"];
+ if (memberOfGroupAttr.length != 0) {
+ for (let value of memberOfGroupAttr) {
+ specificPluginCMD = [...specificPluginCMD, value.label];
+ }
+ } else {
+ specificPluginCMD = [...specificPluginCMD, "delete"];
+ }
+
return (
<div>
+ <Modal show={fixupModalShow} onHide={this.toggleFixupModal}>
+ <div className="ds-no-horizontal-scrollbar">
+ <Modal.Header>
+ <button
+ className="close"
+ onClick={this.toggleFixupModal}
+ aria-hidden="true"
+ aria-label="Close"
+ >
+ <Icon type="pf" name="close" />
+ </button>
+ <Modal.Title>Fixup MemberOf Task</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <Row>
+ <Col sm={12}>
+ <Form horizontal>
+ <FormGroup controlId="fixupDN" key="fixupDN">
+ <Col sm={3}>
+ <ControlLabel>Base DN</ControlLabel>
+ </Col>
+ <Col sm={9}>
+ <FormControl
+ type="text"
+ value={fixupDN}
+ onChange={this.handleFieldChange}
+ />
+ </Col>
+ </FormGroup>
+ <FormGroup controlId="fixupFilter" key="fixupFilter">
+ <Col sm={3}>
+ <ControlLabel>Filter DN</ControlLabel>
+ </Col>
+ <Col sm={9}>
+ <FormControl
+ type="text"
+ value={fixupFilter}
+ onChange={this.handleFieldChange}
+ />
+ </Col>
+ </FormGroup>
+ </Form>
+ </Col>
+ </Row>
+ </Modal.Body>
+ <Modal.Footer>
+ <Button
+ bsStyle="default"
+ className="btn-cancel"
+ onClick={this.toggleFixupModal}
+ >
+ Cancel
+ </Button>
+ <Button bsStyle="primary" onClick={this.runFixup}>
+ Run
+ </Button>
+ </Modal.Footer>
+ </div>
+ </Modal>
+ <Modal show={configEntryModalShow} onHide={this.closeModal}>
+ <div className="ds-no-horizontal-scrollbar">
+ <Modal.Header>
+ <button
+ className="close"
+ onClick={this.closeModal}
+ aria-hidden="true"
+ aria-label="Close"
+ >
+ <Icon type="pf" name="close" />
+ </button>
+ <Modal.Title>Manage MemberOf Plugin Shared Config Entry</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <Row>
+ <Col sm={12}>
+ <Form horizontal>
+ <FormGroup controlId="configDN">
+ <Col sm={3}>
+ <ControlLabel>Config DN</ControlLabel>
+ </Col>
+ <Col sm={9}>
+ <FormControl
+ type="text"
+ value={configDN}
+ onChange={this.handleFieldChange}
+ disabled={!newEntry}
+ />
+ </Col>
+ </FormGroup>
+ <FormGroup
+ key="configAttr"
+ controlId="configAttr"
+ disabled={false}
+ >
+ <Col componentClass={ControlLabel} sm={3}>
+ Attribute
+ </Col>
+ <Col sm={9}>
+ <Typeahead
+ allowNew
+ multiple
+ onChange={values => {
+ this.setState({
+ configAttr: values
+ });
+ }}
+ selected={configAttr}
+ newSelectionPrefix="Add a member: "
+ options={[
+ {
+ id: "memberOf",
+ label: "memberOf"
+ }
+ ]}
+ placeholder="Type a member attribute..."
+ />
+ </Col>
+ </FormGroup>
+ <FormGroup
+ key="configGroupAttr"
+ controlId="configGroupAttr"
+ disabled={false}
+ >
+ <Col componentClass={ControlLabel} sm={3}>
+ Group Attribute
+ </Col>
+ <Col sm={9}>
+ <Typeahead
+ allowNew
+ multiple
+ onChange={values => {
+ this.setState({
+ configGroupAttr: values
+ });
+ }}
+ selected={configGroupAttr}
+ newSelectionPrefix="Add a group member: "
+ options={[
+ {
+ id: "member",
+ label: "member"
+ }
+ ]}
+ placeholder="Type a member group attribute..."
+ />
+ </Col>
+ </FormGroup>
+ </Form>
+ </Col>
+ </Row>
+ <Row>
+ <Col sm={12}>
+ <Form horizontal>
+ <FormGroup
+ key="configEntryScope"
+ controlId="configEntryScope"
+ disabled={false}
+ >
+ <Col componentClass={ControlLabel} sm={3}>
+ Entry Scope
+ </Col>
+ <Col sm={6}>
+ <FormControl
+ type="text"
+ value={configEntryScope}
+ onChange={this.handleFieldChange}
+ />
+ </Col>
+ <Col sm={3}>
+ <Checkbox
+ id="configAllBackends"
+ checked={configAllBackends}
+ onChange={this.handleCheckboxChange}
+ >
+ All Backends
+ </Checkbox>
+ </Col>
+ </FormGroup>
+ <FormGroup
+ key="configEntryScopeExcludeSubtree"
+ controlId="configEntryScopeExcludeSubtree"
+ disabled={false}
+ >
+ <Col componentClass={ControlLabel} sm={3}>
+ Entry Scope Exclude Subtree
+ </Col>
+ <Col sm={6}>
+ <FormControl
+ type="text"
+ value={configEntryScopeExcludeSubtree}
+ onChange={this.handleFieldChange}
+ />
+ </Col>
+ <Col sm={3}>
+ <Checkbox
+ id="configSkipNested"
+ checked={configSkipNested}
+ onChange={this.handleCheckboxChange}
+ >
+ Skip Nested
+ </Checkbox>
+ </Col>
+ </FormGroup>
+ </Form>
+ </Col>
+ </Row>
+ <Row>
+ <Col sm={12}>
+ <Form horizontal>
+ <FormGroup controlId="configAutoAddOC" disabled={false}>
+ <Col sm={3}>
+ <ControlLabel>Auto Add OC</ControlLabel>
+ </Col>
+ <Col sm={9}>
+ <FormControl
+ type="text"
+ value={configAutoAddOC}
+ onChange={this.handleFieldChange}
+ />
+ </Col>
+ </FormGroup>
+ </Form>
+ </Col>
+ </Row>
+ </Modal.Body>
+ <Modal.Footer>
+ <Button
+ bsStyle="default"
+ className="btn-cancel"
+ onClick={this.closeModal}
+ >
+ Cancel
+ </Button>
+ <Button
+ bsStyle="primary"
+ onClick={this.deleteConfig}
+ disabled={newEntry}
+ >
+ Delete
+ </Button>
+ <Button bsStyle="primary" onClick={this.editConfig} disabled={newEntry}>
+ Save
+ </Button>
+ <Button bsStyle="primary" onClick={this.addConfig} disabled={!newEntry}>
+ Add
+ </Button>
+ </Modal.Footer>
+ </div>
+ </Modal>
<PluginBasicConfig
rows={this.props.rows}
serverId={this.props.serverId}
cn="MemberOf Plugin"
pluginName="MemberOf"
cmdName="memberof"
+ specificPluginCMD={specificPluginCMD}
savePluginHandler={this.props.savePluginHandler}
pluginListHandler={this.props.pluginListHandler}
addNotification={this.props.addNotification}
toggleLoadingHandler={this.props.toggleLoadingHandler}
- />
+ >
+ <Row>
+ <Col sm={9}>
+ <Form horizontal>
+ <FormGroup
+ key="memberOfAttr"
+ controlId="memberOfAttr"
+ disabled={false}
+ >
+ <Col componentClass={ControlLabel} sm={3}>
+ Attribute
+ </Col>
+ <Col sm={9}>
+ <Typeahead
+ allowNew
+ multiple
+ onChange={values => {
+ this.setState({
+ memberOfAttr: values
+ });
+ }}
+ selected={memberOfAttr}
+ newSelectionPrefix="Add a member: "
+ options={[
+ {
+ id: "member",
+ label: "member"
+ },
+ {
+ id: "memberCertificate",
+ label: "memberCertificate"
+ },
+ {
+ id: "uniqueMember",
+ label: "uniqueMember"
+ }
+ ]}
+ placeholder="Type a member attribute..."
+ />
+ </Col>
+ </FormGroup>
+ <FormGroup
+ key="memberOfGroupAttr"
+ controlId="memberOfGroupAttr"
+ disabled={false}
+ >
+ <Col componentClass={ControlLabel} sm={3}>
+ Group Attribute
+ </Col>
+ <Col sm={9}>
+ <Typeahead
+ allowNew
+ multiple
+ onChange={values => {
+ this.setState({
+ memberOfGroupAttr: values
+ });
+ }}
+ selected={memberOfGroupAttr}
+ newSelectionPrefix="Add a group member: "
+ options={[
+ {
+ id: "groupOfNames",
+ label: "groupOfNames"
+ },
+ {
+ id: "groupOfURLs",
+ label: "groupOfURLs"
+ },
+ {
+ id: "groupOfUniqueNames",
+ label: "groupOfUniqueNames"
+ },
+ {
+ id: "groupOfCertificates",
+ label: "groupOfCertificates"
+ }
+ ]}
+ placeholder="Type a member group attribute..."
+ />
+ </Col>
+ </FormGroup>
+ </Form>
+ </Col>
+ </Row>
+ <Row>
+ <Col sm={9}>
+ <Form horizontal>
+ <FormGroup
+ key="memberOfEntryScope"
+ controlId="memberOfEntryScope"
+ disabled={false}
+ >
+ <Col componentClass={ControlLabel} sm={3}>
+ Entry Scope
+ </Col>
+ <Col sm={6}>
+ <FormControl
+ type="text"
+ value={memberOfEntryScope}
+ onChange={this.handleFieldChange}
+ />
+ </Col>
+ <Col sm={3}>
+ <Checkbox
+ id="memberOfAllBackends"
+ checked={memberOfAllBackends}
+ onChange={this.handleCheckboxChange}
+ >
+ All Backends
+ </Checkbox>
+ </Col>
+ </FormGroup>
+ <FormGroup
+ key="memberOfEntryScopeExcludeSubtree"
+ controlId="memberOfEntryScopeExcludeSubtree"
+ disabled={false}
+ >
+ <Col componentClass={ControlLabel} sm={3}>
+ Entry Scope Exclude Subtree
+ </Col>
+ <Col sm={6}>
+ <FormControl
+ type="text"
+ value={memberOfEntryScopeExcludeSubtree}
+ onChange={this.handleFieldChange}
+ />
+ </Col>
+ <Col sm={3}>
+ <Checkbox
+ id="memberOfSkipNested"
+ checked={memberOfSkipNested}
+ onChange={this.handleCheckboxChange}
+ >
+ Skip Nested
+ </Checkbox>
+ </Col>
+ </FormGroup>
+ </Form>
+ </Col>
+ </Row>
+ <Row>
+ <Col sm={9}>
+ <Form horizontal>
+ <FormGroup
+ key="memberOfConfigEntry"
+ controlId="memberOfConfigEntry"
+ >
+ <Col componentClass={ControlLabel} sm={3}>
+ Shared Config Entry
+ </Col>
+ <Col sm={6}>
+ <FormControl
+ type="text"
+ value={memberOfConfigEntry}
+ onChange={this.handleFieldChange}
+ />
+ </Col>
+ <Col sm={3}>
+ <Button
+ bsSize="large"
+ bsStyle="primary"
+ onClick={this.openModal}
+ >
+ Manage
+ </Button>
+ </Col>
+ </FormGroup>
+ </Form>
+ </Col>
+ </Row>
+ <Row>
+ <Col sm={9}>
+ <Form horizontal>
+ <FormGroup controlId="memberOfAutoAddOC" disabled={false}>
+ <Col sm={3}>
+ <ControlLabel>Auto Add OC</ControlLabel>
+ </Col>
+ <Col sm={9}>
+ <FormControl
+ type="text"
+ value={memberOfAutoAddOC}
+ onChange={this.handleFieldChange}
+ />
+ </Col>
+ </FormGroup>
+ </Form>
+ </Col>
+ </Row>
+ <Row>
+ <Col sm={9}>
+ <Button
+ bsSize="large"
+ bsStyle="primary"
+ onClick={this.toggleFixupModal}
+ >
+ Run Fixup Task
+ </Button>
+ </Col>
+ </Row>
+ </PluginBasicConfig>
</div>
);
}
diff --git a/src/cockpit/389-console/src/lib/plugins/pluginBasicConfig.jsx b/src/cockpit/389-console/src/lib/plugins/pluginBasicConfig.jsx
index a61356e..ae37334 100644
--- a/src/cockpit/389-console/src/lib/plugins/pluginBasicConfig.jsx
+++ b/src/cockpit/389-console/src/lib/plugins/pluginBasicConfig.jsx
@@ -43,7 +43,9 @@ class PluginBasicConfig extends React.Component {
currentPluginId: "",
currentPluginVendor: "",
currentPluginVersion: "",
- currentPluginDescription: ""
+ currentPluginDescription: "",
+ currentPluginDependsOnType: "",
+ currentPluginDependsOnNamed: ""
};
}
@@ -62,9 +64,7 @@ class PluginBasicConfig extends React.Component {
addNotification,
toggleLoadingHandler
} = this.props;
- const new_status = this.state.currentPluginEnabled
- ? "disable"
- : "enable";
+ const new_status = this.state.currentPluginEnabled ? "disable" : "enable";
const cmd = [
"dsconf",
"-j",
@@ -76,11 +76,7 @@ class PluginBasicConfig extends React.Component {
toggleLoadingHandler();
this.setState({ disableSwitch: true });
- log_cmd(
- "handleSwitchChange",
- "Switch plugin states from the plugin tab",
- cmd
- );
+ log_cmd("handleSwitchChange", "Switch plugin states from the plugin tab", cmd);
cockpit
.spawn(cmd, { superuser: true, err: "message" })
.done(content => {
@@ -88,7 +84,8 @@ class PluginBasicConfig extends React.Component {
pluginListHandler();
addNotification(
"success",
- `${pluginName} plugin was successfully ${new_status}d`
+ `${pluginName} plugin was successfully ${new_status}d.
+ Please, restart the instance.`
);
toggleLoadingHandler();
})
@@ -104,9 +101,7 @@ class PluginBasicConfig extends React.Component {
updateFields() {
if (this.props.rows.length > 0) {
- const pluginRow = this.props.rows.find(
- row => row.cn[0] === this.props.cn
- );
+ const pluginRow = this.props.rows.find(row => row.cn[0] === this.props.cn);
this.setState({
currentPluginType: pluginRow["nsslapd-pluginType"][0],
@@ -115,8 +110,15 @@ class PluginBasicConfig extends React.Component {
currentPluginId: pluginRow["nsslapd-pluginId"][0],
currentPluginVendor: pluginRow["nsslapd-pluginVendor"][0],
currentPluginVersion: pluginRow["nsslapd-pluginVersion"][0],
- currentPluginDescription:
- pluginRow["nsslapd-pluginDescription"][0]
+ currentPluginDescription: pluginRow["nsslapd-pluginDescription"][0],
+ currentPluginDependsOnType:
+ pluginRow["nsslapd-plugin-depends-on-type"] === undefined
+ ? ""
+ : pluginRow["nsslapd-plugin-depends-on-type"][0],
+ currentPluginDependsOnNamed:
+ pluginRow["nsslapd-plugin-depends-on-named"] === undefined
+ ? ""
+ : pluginRow["nsslapd-plugin-depends-on-named"][0]
});
}
this.updateSwitch();
@@ -124,9 +126,7 @@ class PluginBasicConfig extends React.Component {
updateSwitch() {
if (this.props.rows.length > 0) {
- const pluginRow = this.props.rows.find(
- row => row.cn[0] === this.props.cn
- );
+ const pluginRow = this.props.rows.find(row => row.cn[0] === this.props.cn);
var pluginEnabled;
if (pluginRow["nsslapd-pluginEnabled"][0] === "on") {
@@ -158,19 +158,21 @@ class PluginBasicConfig extends React.Component {
currentPluginVendor,
currentPluginVersion,
currentPluginDescription,
+ currentPluginDependsOnType,
+ currentPluginDependsOnNamed,
disableSwitch
} = this.state;
const modalFieldsCol1 = {
currentPluginType: this.state.currentPluginType,
currentPluginPath: this.state.currentPluginPath,
- currentPluginInitfunc: this.state.currentPluginInitfunc,
- currentPluginId: this.state.currentPluginId
+ currentPluginInitfunc: this.state.currentPluginInitfunc
};
const modalFieldsCol2 = {
currentPluginVendor: this.state.currentPluginVendor,
currentPluginVersion: this.state.currentPluginVersion,
- currentPluginDescription: this.state.currentPluginDescription
+ currentPluginDescription: this.state.currentPluginDescription,
+ currentPluginId: this.state.currentPluginId
};
return (
<div>
@@ -184,11 +186,10 @@ class PluginBasicConfig extends React.Component {
</h3>
</Col>
<Col smOffset={1} sm={3}>
- <FormGroup
- key="switchPluginStatus"
- controlId="switchPluginStatus"
- >
- <ControlLabel className="toolbar-pf-find ds-float-left ds-right-indent">
+ <FormGroup key="switchPluginStatus" controlId="switchPluginStatus">
+ <ControlLabel
+ className="toolbar-pf-find ds-float-left ds-right-indent"
+ >
Status
</ControlLabel>
<Switch
@@ -196,11 +197,7 @@ class PluginBasicConfig extends React.Component {
title="normal"
id="bsSize-example"
value={currentPluginEnabled}
- onChange={() =>
- this.handleSwitchChange(
- currentPluginEnabled
- )
- }
+ onChange={() => this.handleSwitchChange(currentPluginEnabled)}
animate={false}
disabled={disableSwitch}
/>
@@ -213,94 +210,100 @@ class PluginBasicConfig extends React.Component {
<Row>
<Col sm={4}>
<Form horizontal>
- {Object.entries(modalFieldsCol1).map(
- ([id, value]) => (
- <FormGroup
- key={id}
- controlId={id}
- disabled={false}
- >
- <Col
- componentClass={ControlLabel}
- sm={4}
- >
- Plugin{" "}
- {id.replace(
- "currentPlugin",
- ""
- )}
- </Col>
- <Col sm={8}>
- <FormControl
- type="text"
- value={value}
- onChange={
- this.handleFieldChange
- }
- />
- </Col>
- </FormGroup>
- )
- )}
+ {Object.entries(modalFieldsCol1).map(([id, value]) => (
+ <FormGroup key={id} controlId={id} disabled={false}>
+ <Col componentClass={ControlLabel} sm={6}>
+ {this.props.memberOfAttr} Plugin{" "}
+ {id.replace("currentPlugin", "")}
+ </Col>
+ <Col sm={6}>
+ <FormControl
+ type="text"
+ value={value}
+ onChange={this.handleFieldChange}
+ />
+ </Col>
+ </FormGroup>
+ ))}
+ <FormGroup
+ key="currentPluginDependsOnType"
+ controlId="currentPluginDependsOnType"
+ disabled={false}
+ >
+ <Col componentClass={ControlLabel} sm={6}>
+ Plugin Depends On Type
+ </Col>
+ <Col sm={6}>
+ <FormControl
+ type="text"
+ value={this.state.currentPluginDependsOnType}
+ onChange={this.handleFieldChange}
+ />
+ </Col>
+ </FormGroup>
+ <FormGroup
+ key="currentPluginDependsOnNamed"
+ controlId="currentPluginDependsOnNamed"
+ disabled={false}
+ >
+ <Col componentClass={ControlLabel} sm={6}>
+ Plugin Depends On Named
+ </Col>
+ <Col sm={6}>
+ <FormControl
+ type="text"
+ value={this.state.currentPluginDependsOnNamed}
+ onChange={this.handleFieldChange}
+ />
+ </Col>
+ </FormGroup>
</Form>
</Col>
<Col sm={4}>
<Form horizontal>
- {Object.entries(modalFieldsCol2).map(
- ([id, value]) => (
- <FormGroup
- key={id}
- controlId={id}
- disabled={false}
- >
- <Col
- componentClass={ControlLabel}
- sm={4}
- >
- Plugin{" "}
- {id.replace(
- "currentPlugin",
- ""
- )}
- </Col>
- <Col sm={8}>
- <FormControl
- type="text"
- value={value}
- onChange={
- this.handleFieldChange
- }
- />
- </Col>
- </FormGroup>
- )
- )}
+ {Object.entries(modalFieldsCol2).map(([id, value]) => (
+ <FormGroup key={id} controlId={id} disabled={false}>
+ <Col componentClass={ControlLabel} sm={5}>
+ Plugin {id.replace("currentPlugin", "")}
+ </Col>
+ <Col sm={7}>
+ <FormControl
+ type="text"
+ value={value}
+ onChange={this.handleFieldChange}
+ />
+ </Col>
+ </FormGroup>
+ ))}
</Form>
</Col>
</Row>
- <Row>
- <Col smOffset={7} sm={1}>
- <Button
- bsSize="large"
- bsStyle="primary"
- onClick={() =>
- this.props.savePluginHandler({
- name: this.props.cn,
- type: currentPluginType,
- path: currentPluginPath,
- initfunc: currentPluginInitfunc,
- id: currentPluginId,
- vendor: currentPluginVendor,
- version: currentPluginVersion,
- description: currentPluginDescription
- })
- }
- >
- Save Config
- </Button>
- </Col>
- </Row>
</CustomCollapse>
+ <Row>
+ <Col smOffset={7} sm={1}>
+ <Button
+ bsSize="large"
+ bsStyle="primary"
+ onClick={() =>
+ this.props.savePluginHandler({
+ name: this.props.cn,
+ type: currentPluginType,
+ path: currentPluginPath,
+ initfunc: currentPluginInitfunc,
+ id: currentPluginId,
+ vendor: currentPluginVendor,
+ version: currentPluginVersion,
+ description: currentPluginDescription,
+ dependsOnType: currentPluginDependsOnType,
+ dependsOnNamed: currentPluginDependsOnNamed,
+ specificPluginCMD: this.props.specificPluginCMD
+ })
+ }
+ >
+ Save Config
+ </Button>
+ </Col>
+ </Row>
</div>
);
}
@@ -313,6 +316,7 @@ PluginBasicConfig.propTypes = {
cn: PropTypes.string,
pluginName: PropTypes.string,
cmdName: PropTypes.string,
+ specificPluginCMD: PropTypes.array,
savePluginHandler: PropTypes.func,
pluginListHandler: PropTypes.func,
addNotification: PropTypes.func,
@@ -325,6 +329,7 @@ PluginBasicConfig.defaultProps = {
cn: "",
pluginName: "",
cmdName: "",
+ specificPluginCMD: [],
savePluginHandler: noop,
pluginListHandler: noop,
addNotification: noop,
diff --git a/src/cockpit/389-console/src/lib/plugins/pluginModal.jsx b/src/cockpit/389-console/src/lib/plugins/pluginModal.jsx
index 2572475..d8358e9 100644
--- a/src/cockpit/389-console/src/lib/plugins/pluginModal.jsx
+++ b/src/cockpit/389-console/src/lib/plugins/pluginModal.jsx
@@ -16,18 +16,14 @@ import "../../css/ds.css";
class PluginEditModal extends React.Component {
render() {
- const modalFields = {
- currentPluginType: this.props.currentPluginType,
- currentPluginPath: this.props.currentPluginPath,
- currentPluginInitfunc: this.props.currentPluginInitfunc,
- currentPluginId: this.props.currentPluginId,
- currentPluginVendor: this.props.currentPluginVendor,
- currentPluginVersion: this.props.currentPluginVersion,
- currentPluginDescription: this.props.currentPluginDescription
- };
const {
showModal,
closeHandler,
+ handleChange,
+ handleSwitchChange,
+ savePluginHandler
+ } = this.props;
+ const {
currentPluginName,
currentPluginEnabled,
currentPluginType,
@@ -37,10 +33,19 @@ class PluginEditModal extends React.Component {
currentPluginVendor,
currentPluginVersion,
currentPluginDescription,
- handleChange,
- handleSwitchChange,
- savePluginHandler
- } = this.props;
+ currentPluginDependsOnType,
+ currentPluginDependsOnNamed
+ } = this.props.pluginData;
+ const modalFields = {
+ currentPluginType: currentPluginType,
+ currentPluginPath: currentPluginPath,
+ currentPluginInitfunc: currentPluginInitfunc,
+ currentPluginId: currentPluginId,
+ currentPluginVendor: currentPluginVendor,
+ currentPluginVersion: currentPluginVersion,
+ currentPluginDescription: currentPluginDescription
+ };
+
return (
<Modal show={showModal} onHide={closeHandler}>
<div className="ds-no-horizontal-scrollbar">
@@ -53,9 +58,7 @@ class PluginEditModal extends React.Component {
>
<Icon type="pf" name="close" />
</button>
- <Modal.Title>
- Edit Plugin - {currentPluginName}
- </Modal.Title>
+ <Modal.Title>Edit Plugin - {currentPluginName}</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form horizontal>
@@ -64,34 +67,26 @@ class PluginEditModal extends React.Component {
controlId="currentPluginEnabled"
disabled={false}
>
- <Col componentClass={ControlLabel} sm={4}>
+ <Col componentClass={ControlLabel} sm={6}>
Plugin Status
</Col>
- <Col sm={7}>
+ <Col sm={6}>
<Switch
bsSize="normal"
title="normal"
id="pluginEnableSwitch"
value={currentPluginEnabled}
- onChange={() =>
- handleSwitchChange(
- currentPluginEnabled
- )
- }
+ onChange={() => handleSwitchChange(currentPluginEnabled)}
animate={false}
/>
</Col>
</FormGroup>
{Object.entries(modalFields).map(([id, value]) => (
- <FormGroup
- key={id}
- controlId={id}
- disabled={false}
- >
- <Col componentClass={ControlLabel} sm={4}>
+ <FormGroup key={id} controlId={id} disabled={false}>
+ <Col componentClass={ControlLabel} sm={6}>
Plugin {id.replace("currentPlugin", "")}
</Col>
- <Col sm={7}>
+ <Col sm={6}>
<FormControl
type="text"
value={value}
@@ -100,29 +95,61 @@ class PluginEditModal extends React.Component {
</Col>
</FormGroup>
))}
+ <FormGroup
+ key="currentPluginDependsOnType"
+ controlId="currentPluginDependsOnType"
+ disabled={false}
+ >
+ <Col componentClass={ControlLabel} sm={6}>
+ Plugin Depends On Type
+ </Col>
+ <Col sm={6}>
+ <FormControl
+ type="text"
+ value={currentPluginDependsOnType}
+ onChange={handleChange}
+ />
+ </Col>
+ </FormGroup>
+ <FormGroup
+ key="currentPluginDependsOnNamed"
+ controlId="currentPluginDependsOnNamed"
+ disabled={false}
+ >
+ <Col componentClass={ControlLabel} sm={6}>
+ Plugin Depends On Type
+ </Col>
+ <Col sm={6}>
+ <FormControl
+ type="text"
+ value={currentPluginDependsOnNamed}
+ onChange={handleChange}
+ />
+ </Col>
+ </FormGroup>
</Form>
</Modal.Body>
- <Modal.Footer className="ds-modal-footer">
- <Button
- bsStyle="default"
- className="btn-cancel"
- onClick={closeHandler}
- >
+ <Modal.Footer>
+ <Button bsStyle="default" className="btn-cancel" onClick={closeHandler}>
Cancel
</Button>
<Button
bsStyle="primary"
- onClick={() => savePluginHandler({
- name: currentPluginName,
- enabled: currentPluginEnabled,
- type: currentPluginType,
- path: currentPluginPath,
- initfunc: currentPluginInitfunc,
- id: currentPluginId,
- vendor: currentPluginVendor,
- version: currentPluginVersion,
- description: currentPluginDescription
- })}
+ onClick={() =>
+ savePluginHandler({
+ name: currentPluginName,
+ enabled: currentPluginEnabled,
+ type: currentPluginType,
+ path: currentPluginPath,
+ initfunc: currentPluginInitfunc,
+ id: currentPluginId,
+ vendor: currentPluginVendor,
+ version: currentPluginVersion,
+ description: currentPluginDescription,
+ dependsOnType: currentPluginDependsOnType,
+ dependsOnNamed: currentPluginDependsOnNamed
+ })
+ }
>
Save
</Button>
@@ -136,15 +163,19 @@ class PluginEditModal extends React.Component {
PluginEditModal.propTypes = {
handleChange: PropTypes.func,
handleSwitchChange: PropTypes.func,
- currentPluginName: PropTypes.string,
- currentPluginType: PropTypes.string,
- currentPluginEnabled: PropTypes.bool,
- currentPluginPath: PropTypes.string,
- currentPluginInitfunc: PropTypes.string,
- currentPluginId: PropTypes.string,
- currentPluginVendor: PropTypes.string,
- currentPluginVersion: PropTypes.string,
- currentPluginDescription: PropTypes.string,
+ pluginData: PropTypes.exact({
+ currentPluginName: PropTypes.string,
+ currentPluginType: PropTypes.string,
+ currentPluginEnabled: PropTypes.bool,
+ currentPluginPath: PropTypes.string,
+ currentPluginInitfunc: PropTypes.string,
+ currentPluginId: PropTypes.string,
+ currentPluginVendor: PropTypes.string,
+ currentPluginVersion: PropTypes.string,
+ currentPluginDescription: PropTypes.string,
+ currentPluginDependsOnType: PropTypes.string,
+ currentPluginDependsOnNamed: PropTypes.string
+ }),
closeHandler: PropTypes.func,
savePluginHandler: PropTypes.func,
showModal: PropTypes.bool
@@ -153,15 +184,19 @@ PluginEditModal.propTypes = {
PluginEditModal.defaultProps = {
handleChange: noop,
handleSwitchChange: noop,
- currentPluginName: "",
- currentPluginType: "",
- currentPluginEnabled: false,
- currentPluginPath: "",
- currentPluginInitfunc: "",
- currentPluginId: "",
- currentPluginVendor: "",
- currentPluginVersion: "",
- currentPluginDescription: "",
+ pluginData: {
+ currentPluginName: "",
+ currentPluginType: "",
+ currentPluginEnabled: false,
+ currentPluginPath: "",
+ currentPluginInitfunc: "",
+ currentPluginId: "",
+ currentPluginVendor: "",
+ currentPluginVersion: "",
+ currentPluginDescription: "",
+ currentPluginDependsOnType: "",
+ currentPluginDependsOnNamed: ""
+ },
closeHandler: noop,
savePluginHandler: noop,
showModal: false
diff --git a/src/cockpit/389-console/src/plugins.jsx b/src/cockpit/389-console/src/plugins.jsx
index 7afb619..2b455ba 100644
--- a/src/cockpit/389-console/src/plugins.jsx
+++ b/src/cockpit/389-console/src/plugins.jsx
@@ -69,7 +69,9 @@ export class Plugins extends React.Component {
currentPluginId: "",
currentPluginVendor: "",
currentPluginVersion: "",
- currentPluginDescription: ""
+ currentPluginDescription: "",
+ currentPluginDependsOnType: "",
+ currentPluginDependsOnNamed: ""
};
}
@@ -147,6 +149,14 @@ export class Plugins extends React.Component {
currentPluginVendor: rowData["nsslapd-pluginVendor"][0],
currentPluginVersion: rowData["nsslapd-pluginVersion"][0],
currentPluginDescription: rowData["nsslapd-pluginDescription"][0],
+ currentPluginDependsOnType:
+ rowData["nsslapd-plugin-depends-on-type"] === undefined
+ ? ""
+ : rowData["nsslapd-plugin-depends-on-type"][0],
+ currentPluginDependsOnNamed:
+ rowData["nsslapd-plugin-depends-on-named"] === undefined
+ ? ""
+ : rowData["nsslapd-plugin-depends-on-named"][0],
showPluginModal: true
});
}
@@ -179,7 +189,9 @@ export class Plugins extends React.Component {
}
savePlugin(data) {
- cmd = [
+ let nothingToSetErr = false;
+ let basicPluginSuccess = false;
+ let cmd = [
"dsconf",
"-j",
"ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket",
@@ -187,19 +199,23 @@ export class Plugins extends React.Component {
"edit",
data.name,
"--type",
- data.type,
+ data.type || "delete",
"--path",
- data.path,
+ data.path || "delete",
"--initfunc",
- data.initfunc,
+ data.initfunc || "delete",
"--id",
- data.id,
+ data.id || "delete",
"--vendor",
- data.vendor,
+ data.vendor || "delete",
"--version",
- data.version,
+ data.version || "delete",
"--description",
- data.description
+ data.description || "delete",
+ "--depends-on-type",
+ data.dependsOnType || "delete",
+ "--depends-on-named",
+ data.dependsOnNamed || "delete"
];
if ("enabled" in data) {
@@ -207,26 +223,80 @@ export class Plugins extends React.Component {
}
this.toggleLoading();
- log_cmd("savePlugin", "Edit the plugin from the modal form", cmd);
+
+ log_cmd("savePlugin", "Edit the plugin", cmd);
cockpit
.spawn(cmd, { superuser: true, err: "message" })
.done(content => {
console.info("savePlugin", "Result", content);
+ basicPluginSuccess = true;
this.addNotification(
"success",
`Plugin ${data.name} was successfully modified`
);
- this.pluginList();
this.closePluginModal();
this.toggleLoading();
})
.fail(err => {
- this.addNotification(
- "error",
- `Error during plugin ${data.name} modification - ${err}`
- );
+ if (err.message.indexOf("nothing to set") >= 0) {
+ nothingToSetErr = true;
+ } else {
+ this.addNotification(
+ "error",
+ `${err.message} error during ${data.name} modification`
+ );
+ }
this.closePluginModal();
this.toggleLoading();
+ })
+ .always(() => {
+ if ("specificPluginCMD" in data) {
+ this.toggleLoading();
+ log_cmd(
+ "savePlugin",
+ "Edit the plugin from the plugin config tab",
+ data.specificPluginCMD
+ );
+ cockpit
+ .spawn(data.specificPluginCMD, {
+ superuser: true,
+ err: "message"
+ })
+ .done(content => {
+ // Notify success only one time
+ if (!basicPluginSuccess) {
+ this.addNotification(
+ "success",
+ `Plugin ${data.name} was successfully modified`
+ );
+ }
+ this.pluginList();
+ this.toggleLoading();
+ console.info("savePlugin", "Result", content);
+ })
+ .fail(err => {
+ if (
+ (err.message.indexOf(
+ "nothing to set"
+ ) >= 0 &&
+ nothingToSetErr) ||
+ err.message.indexOf("nothing to set") < 0
+ ) {
+ if (basicPluginSuccess) {
+ this.addNotification(
+ "success",
+ `Plugin ${data.name} was successfully modified`
+ );
+ this.pluginList();
+ }
+ this.addNotification(
+ "error",
+ `${err.message} error during ${data.name} modification`
+ );
+ }
+ this.toggleLoading();
+ });
+ }
});
}
@@ -235,10 +305,7 @@ export class Plugins extends React.Component {
allPlugins: {
name: "All Plugins",
component: (
- <PluginTable
- rows={this.state.rows}
- loadModalHandler={this.openPluginModal}
- />
+ <PluginTable rows={this.state.rows} loadModalHandler={this.openPluginModal} />
)
},
accountPolicy: {
@@ -424,24 +491,20 @@ export class Plugins extends React.Component {
<Row className="clearfix">
<Col sm={2}>
<Nav bsStyle="pills" stacked>
- {Object.entries(selectPlugins).map(
- ([id, item]) => (
- <NavItem key={id} eventKey={id}>
- {item.name}
- </NavItem>
- )
- )}
+ {Object.entries(selectPlugins).map(([id, item]) => (
+ <NavItem key={id} eventKey={id}>
+ {item.name}
+ </NavItem>
+ ))}
</Nav>
</Col>
<Col sm={10}>
<Tab.Content animation={false}>
- {Object.entries(selectPlugins).map(
- ([id, item]) => (
- <Tab.Pane key={id} eventKey={id}>
- {item.component}
- </Tab.Pane>
- )
- )}
+ {Object.entries(selectPlugins).map(([id, item]) => (
+ <Tab.Pane key={id} eventKey={id}>
+ {item.component}
+ </Tab.Pane>
+ ))}
</Tab.Content>
</Col>
</Row>
@@ -449,17 +512,19 @@ export class Plugins extends React.Component {
<PluginEditModal
handleChange={this.handleFieldChange}
handleSwitchChange={this.handleSwitchChange}
- currentPluginName={this.state.currentPluginName}
- currentPluginType={this.state.currentPluginType}
- currentPluginEnabled={this.state.currentPluginEnabled}
- currentPluginPath={this.state.currentPluginPath}
- currentPluginInitfunc={this.state.currentPluginInitfunc}
- currentPluginId={this.state.currentPluginId}
- currentPluginVendor={this.state.currentPluginVendor}
- currentPluginVersion={this.state.currentPluginVersion}
- currentPluginDescription={
- this.state.currentPluginDescription
- }
+ pluginData={{
+ currentPluginName: this.state.currentPluginName,
+ currentPluginType: this.state.currentPluginType,
+ currentPluginEnabled: this.state.currentPluginEnabled,
+ currentPluginPath: this.state.currentPluginPath,
+ currentPluginInitfunc: this.state.currentPluginInitfunc,
+ currentPluginId: this.state.currentPluginId,
+ currentPluginVendor: this.state.currentPluginVendor,
+ currentPluginVersion: this.state.currentPluginVersion,
+ currentPluginDescription: this.state.currentPluginDescription,
+ currentPluginDependsOnType: this.state.currentPluginDependsOnType,
+ currentPluginDependsOnNamed: this.state.currentPluginDependsOnNamed
+ }}
closeHandler={this.closePluginModal}
showModal={this.state.showPluginModal}
savePluginHandler={this.savePlugin}
diff --git a/src/cockpit/389-console/src/static/Typeahead.css b/src/cockpit/389-console/src/static/Typeahead.css
new file mode 100644
index 0000000..0f728f9
--- /dev/null
+++ b/src/cockpit/389-console/src/static/Typeahead.css
@@ -0,0 +1,256 @@
+.rbt {
+ outline: none;
+}
+
+.rbt-menu {
+ margin-bottom: 2px;
+}
+
+.rbt-menu > li a {
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.rbt-menu > li a:focus {
+ outline: none;
+}
+
+.rbt-menu-pagination-option {
+ text-align: center;
+}
+
+.rbt .rbt-input-main::-ms-clear {
+ display: none;
+}
+
+.rbt-input-multi {
+ cursor: text;
+ overflow: hidden;
+ position: relative;
+ height: auto;
+}
+
+.rbt-input-multi.focus {
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
+ border-color: #66afe9;
+ outline: 0;
+}
+
+.rbt-input-multi.form-control[disabled] {
+ background-color: #e9ecef;
+ opacity: 1;
+}
+
+.rbt-input-multi input::-moz-placeholder {
+ color: #999;
+ opacity: 1;
+}
+
+.rbt-input-multi input:-ms-input-placeholder {
+ color: #999;
+}
+
+.rbt-input-multi input::-webkit-input-placeholder {
+ color: #999;
+}
+
+.rbt-input-multi .rbt-input-wrapper {
+ margin-bottom: -4px;
+ margin-top: -1px;
+ overflow: hidden;
+}
+
+.rbt-input-multi .rbt-input-main {
+ height: 20px;
+ margin: 1px 0 4px;
+}
+
+.rbt-input-multi .rbt-input-hint-container {
+ display: inline-block;
+}
+
+.rbt-input-multi.input-lg .rbt-input-main, .rbt-input-multi.form-control-lg .rbt-input-main {
+ height: 24px;
+}
+
+.rbt-input-multi.input-sm .rbt-input-main, .rbt-input-multi.form-control-sm .rbt-input-main {
+ height: 18px;
+}
+
+.rbt-close {
+ z-index: 1;
+}
+
+.rbt-close-lg {
+ font-size: 24px;
+}
+
+.rbt-token {
+ background-color: #e7f4ff;
+ border: 0;
+ border-radius: 2px;
+ color: #1f8dd6;
+ display: inline-block;
+ line-height: 1em;
+ margin: 0 3px 3px 0;
+ padding: 4px 7px;
+ position: relative;
+}
+
+.rbt-token-disabled {
+ background-color: #ddd;
+ color: #888;
+ pointer-events: none;
+}
+
+.rbt-token-removeable {
+ cursor: pointer;
+ padding-right: 21px;
+}
+
+.rbt-token-active {
+ background-color: #1f8dd6;
+ color: #fff;
+ outline: none;
+ text-decoration: none;
+}
+
+.rbt-token .rbt-token-remove-button {
+ bottom: 0;
+ color: inherit;
+ font-size: inherit;
+ font-weight: normal;
+ opacity: 1;
+ outline: none;
+ padding: 3px 7px;
+ position: absolute;
+ right: 0;
+ text-shadow: none;
+ top: -2px;
+}
+
+.rbt-loader {
+ -webkit-animation: loader-animation 600ms infinite linear;
+ -o-animation: loader-animation 600ms infinite linear;
+ animation: loader-animation 600ms infinite linear;
+ border: 1px solid #d5d5d5;
+ border-radius: 50%;
+ border-top-color: #1f8dd6;
+ display: block;
+ height: 16px;
+ width: 16px;
+}
+
+.rbt-loader-lg {
+ height: 20px;
+ width: 20px;
+}
+
+.rbt-aux {
+ display: -webkit-box;
+ display: -moz-box;
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
+ align-items: center;
+ bottom: 0;
+ justify-content: center;
+ pointer-events: none;
+ /* Don't block clicks on the input */
+ position: absolute;
+ right: 0;
+ top: 0;
+ width: 34px;
+}
+
+.rbt-aux-lg {
+ width: 46px;
+}
+
+.rbt-aux .rbt-close {
+ margin-top: -4px;
+ pointer-events: auto;
+ /* Override pointer-events: none; above */
+}
+
+.has-aux .rbt-input {
+ padding-right: 34px;
+}
+
+.rbt-highlight-text {
+ background-color: inherit;
+ color: inherit;
+ font-weight: bold;
+ padding: 0;
+}
+
+/* Input Groups */
+.input-group > .rbt {
+ -webkit-box-flex: 1;
+ -moz-box-flex: 1;
+ -webkit-flex: 1;
+ -ms-flex: 1;
+ flex: 1;
+}
+
+.input-group > .rbt .rbt-input-hint-container {
+ display: -webkit-box;
+ display: -moz-box;
+ display: -ms-flexbox;
+ display: -webkit-flex;
+ display: flex;
+}
+
+.input-group > .rbt .rbt-input-hint {
+ z-index: 5;
+}
+
+.input-group > .rbt .rbt-aux {
+ z-index: 5;
+}
+
+.input-group > .rbt:not(:first-child) .form-control {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.input-group > .rbt:not(:last-child) .form-control {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+/* Validation States */
+.has-error .rbt-input-multi.focus {
+ border-color: #843534;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
+}
+
+.has-warning .rbt-input-multi.focus {
+ border-color: #66512c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
+}
+
+.has-success .rbt-input-multi.focus {
+ border-color: #2b542c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
+}
+
+@keyframes loader-animation {
+ to {
+ transform: rotate(1turn);
+ }
+}
+
+@-webkit-keyframes loader-animation {
+ to {
+ -webkit-transform: rotate(1turn);
+ }
+}
diff --git a/src/cockpit/389-console/webpack.config.js b/src/cockpit/389-console/webpack.config.js
index 6d7cbec..2387cd9 100644
--- a/src/cockpit/389-console/webpack.config.js
+++ b/src/cockpit/389-console/webpack.config.js
@@ -6,24 +6,22 @@ const webpack = require("webpack");
const CompressionPlugin = require("compression-webpack-plugin");
var externals = {
- "cockpit": "cockpit",
+ cockpit: "cockpit"
};
/* These can be overridden, typically from the Makefile.am */
const srcdir = (process.env.SRCDIR || __dirname) + path.sep + "src";
-const builddir = (process.env.SRCDIR || __dirname);
+const builddir = process.env.SRCDIR || __dirname;
const distdir = builddir + path.sep + "dist";
const section = process.env.ONLYDIR || null;
-const nodedir = path.resolve((process.env.SRCDIR || __dirname), "node_modules");
+const nodedir = path.resolve(process.env.SRCDIR || __dirname, "node_modules");
/* A standard nodejs and webpack pattern */
-var production = process.env.NODE_ENV === 'production';
+var production = process.env.NODE_ENV === "production";
var info = {
entries: {
- "index": [
- "./index.es6"
- ]
+ index: ["./index.es6"]
},
files: [
"backend.html",
@@ -46,14 +44,14 @@ var info = {
"servers.html",
"servers.js",
"static",
- "manifest.json",
- ],
+ "manifest.json"
+ ]
};
var output = {
path: distdir,
filename: "[name].js",
- sourceMapFilename: "[file].map",
+ sourceMapFilename: "[file].map"
};
/*
@@ -67,8 +65,7 @@ var output = {
function vpath(/* ... */) {
var filename = Array.prototype.join.call(arguments, path.sep);
var expanded = builddir + path.sep + filename;
- if (fs.existsSync(expanded))
- return expanded;
+ if (fs.existsSync(expanded)) return expanded;
expanded = srcdir + path.sep + filename;
return expanded;
}
@@ -81,10 +78,8 @@ Object.keys(info.entries).forEach(function(key) {
}
info.entries[key] = info.entries[key].map(function(value) {
- if (value.indexOf("/") === -1)
- return value;
- else
- return vpath(value);
+ if (value.indexOf("/") === -1) return value;
+ else return vpath(value);
});
});
@@ -96,26 +91,25 @@ info.files.forEach(function(value) {
});
info.files = files;
-var plugins = [
- new copy(info.files),
- new extract("[name].css")
-];
+var plugins = [new copy(info.files), new extract("[name].css")];
/* Only minimize when in production mode */
if (production) {
/* Rename output files when minimizing */
output.filename = "[name].min.js";
- plugins.unshift(new CompressionPlugin({
- asset: "[path].gz[query]",
- test: /\.(js|html)$/,
- minRatio: 0.9,
- deleteOriginalAssets: true
- }));
+ plugins.unshift(
+ new CompressionPlugin({
+ asset: "[path].gz[query]",
+ test: /\.(js|html)$/,
+ minRatio: 0.9,
+ deleteOriginalAssets: true
+ })
+ );
}
module.exports = {
- mode: production ? 'production' : 'development',
+ mode: production ? "production" : "development",
entry: info.entries,
externals: externals,
output: output,
@@ -123,42 +117,44 @@ module.exports = {
module: {
rules: [
{
- enforce: 'pre',
+ enforce: "pre",
exclude: /node_modules/,
- loader: 'eslint-loader',
+ loader: "eslint-loader",
test: /\.jsx$/
},
{
- enforce: 'pre',
+ enforce: "pre",
exclude: /node_modules/,
- loader: 'eslint-loader',
+ loader: "eslint-loader",
test: /\.es6$/
},
{
exclude: /node_modules/,
- loader: 'babel-loader',
+ loader: "babel-loader",
test: /\.js$/
},
{
exclude: /node_modules/,
- loader: 'babel-loader',
+ loader: "babel-loader",
test: /\.jsx$/
},
{
exclude: /node_modules/,
- loader: 'babel-loader',
+ loader: "babel-loader",
test: /\.es6$/
},
{
+ // Transform our own .css files with PostCSS and CSS-modules
+ test: /\.css$/,
exclude: /node_modules/,
- loader: extract.extract('css-loader!sass-loader'),
- test: /\.scss$/
+ use: ['style-loader', 'css-loader'],
},
{
test: /\.css$/,
- use: [ 'style-loader', 'css-loader' ]
+ include: /node_modules/,
+ use: ['style-loader', 'css-loader'],
}
]
},
plugins: plugins
-}
+};
diff --git a/src/lib389/lib389/_mapped_object.py b/src/lib389/lib389/_mapped_object.py
index e1f9adb..06a2821 100644
--- a/src/lib389/lib389/_mapped_object.py
+++ b/src/lib389/lib389/_mapped_object.py
@@ -270,7 +270,14 @@ class DSLdapObject(DSLogging):
:param *args: tuples of key,value to replace.
:type *args: (str, str)
"""
- mods = list(map(lambda t: (ldap.MOD_REPLACE, ensure_str(t[0]), ensure_bytes(t[1])), args))
+
+ mods = []
+ for arg in args:
+ if isinstance(arg[1], list):
+ value = ensure_list_bytes(arg[1])
+ else:
+ value = [ensure_bytes(arg[1])]
+ mods.append((ldap.MOD_REPLACE, ensure_str(arg[0]), value))
return self._instance.modify_ext_s(self._dn, mods, serverctrls=self._server_controls, clientctrls=self._client_controls)
# This needs to work on key + val, and key
@@ -371,7 +378,7 @@ class DSLdapObject(DSLogging):
def apply_mods(self, mods):
"""Perform modification operation using several mods at once
- :param mods: [(action, key, value),]
+ :param mods: [(action, key, value),] or [(ldap.MOD_DELETE, key),]
:type mods: list of tuples
:raises: ValueError - if a provided mod op is invalid
"""
@@ -381,25 +388,25 @@ class DSLdapObject(DSLogging):
if len(mod) < 2:
# Error
raise ValueError('Not enough arguments in the mod op')
- elif len(mod) == 2: # no action
- action = ldap.MOD_REPLACE
- key, value = mod
+ elif len(mod) == 2: # delete all attributes action
+ action, key = mod
+ if action != ldap.MOD_DELETE:
+ raise ValueError('Not enough arguments in the mod op')
+ mod_list.append((action, key, None))
elif len(mod) == 3:
action, key, value = mod
if action != ldap.MOD_REPLACE and \
action != ldap.MOD_ADD and \
action != ldap.MOD_DELETE:
raise ValueError('Invalid mod action(%s)' % str(action))
+ if isinstance(value, list):
+ value = ensure_list_bytes(value)
+ else:
+ value = [ensure_bytes(value)]
+ mod_list.append((action, key, value))
else:
# Error too many items
raise ValueError('Too many arguments in the mod op')
-
- if isinstance(value, list):
- value = ensure_list_bytes(value)
- else:
- value = [ensure_bytes(value)]
-
- mod_list.append((action, key, value))
return self._instance.modify_ext_s(self._dn, mod_list, serverctrls=self._server_controls, clientctrls=self._client_controls)
@classmethod
diff --git a/src/lib389/lib389/cli_conf/__init__.py b/src/lib389/lib389/cli_conf/__init__.py
index a969724..1ba3b4a 100644
--- a/src/lib389/lib389/cli_conf/__init__.py
+++ b/src/lib389/lib389/cli_conf/__init__.py
@@ -5,6 +5,67 @@
# License: GPL (version 3 or any later version).
# See LICENSE for details.
# --- END COPYRIGHT BLOCK ---
+import ldap
+from lib389 import ensure_list_str
+
+
+def _args_to_attrs(args, arg_to_attr):
+ attrs = {}
+ for arg in vars(args):
+ val = getattr(args, arg)
+ if arg in arg_to_attr and val is not None:
+ attrs[arg_to_attr[arg]] = val
+ elif arg == 'DN':
+ # Extract RDN from the DN
+ attribute = ldap.dn.str2dn(val)[0][0][0]
+ value = ldap.dn.str2dn(val)[0][0][1]
+ attrs[attribute] = value
+ return attrs
+
+
+def generic_object_add(dsldap_object, log, args, arg_to_attr, props={}):
+ """Create an entry using DSLdapObject interface
+
+ dsldap_object should be a single instance of DSLdapObject with a set dn
+ """
+
+ log = log.getChild('generic_object_add')
+ # Gather the attributes
+ attrs = _args_to_attrs(args, arg_to_attr)
+ # Update the parameters (which should have at least 'cn') with arg attributes
+ props.update({attr: value for (attr, value) in attrs.items() if value != ""})
+ new_object = dsldap_object.create(properties=props)
+ log.info("Successfully created the %s", new_object.dn)
+
+
+def generic_object_edit(dsldap_object, log, args, arg_to_attr):
+ """Create an entry using DSLdapObject interface
+
+ dsldap_object should be a single instance of DSLdapObject with a set dn
+ """
+
+ log = log.getChild('generic_object_edit')
+ # Gather the attributes
+ attrs = _args_to_attrs(args, arg_to_attr)
+ existing_attributes = dsldap_object.get_all_attrs()
+
+ modlist = []
+ for attr, value in attrs.items():
+ # Delete the attribute only if the user set it to 'delete' value
+ if value in ("delete", ["delete"]):
+ if attr in existing_attributes:
+ modlist.append((ldap.MOD_DELETE, attr))
+ else:
+ if not isinstance(value, list):
+ value = [value]
+ if not (attr in existing_attributes and value == ensure_list_str(existing_attributes[attr])):
+ modlist.append((ldap.MOD_REPLACE, attr, value))
+ if len(modlist) > 0:
+ dsldap_object.apply_mods(modlist)
+ log.info("Successfully changed the %s", dsldap_object.dn)
+ else:
+ raise ValueError("There is nothing to set in the %s plugin entry" % dsldap_object.dn)
+
def generic_show(inst, basedn, log, args):
"""Display plugin configuration."""
@@ -15,27 +76,27 @@ def generic_show(inst, basedn, log, args):
def generic_enable(inst, basedn, log, args):
plugin = args.plugin_cls(inst)
if plugin.status():
- print("Plugin '%s' already enabled" % plugin.rdn)
+ print("Plugin '%s' already enabled", plugin.rdn)
else:
plugin.enable()
- print("Enabled plugin '%s'" % plugin.rdn)
+ print("Enabled plugin '%s'", plugin.rdn)
def generic_disable(inst, basedn, log, args):
plugin = args.plugin_cls(inst)
if not plugin.status():
- print("Plugin '%s' already disabled " % plugin.rdn)
+ print("Plugin '%s' already disabled", plugin.rdn)
else:
plugin.disable()
- print("Disabled plugin '%s'" % plugin.rdn)
+ print("Disabled plugin '%s'", plugin.rdn)
def generic_status(inst, basedn, log, args):
plugin = args.plugin_cls(inst)
if plugin.status() is True:
- print("Plugin '%s' is enabled" % plugin.rdn)
+ print("Plugin '%s' is enabled", plugin.rdn)
else:
- print("Plugin '%s' is disabled" % plugin.rdn)
+ print("Plugin '%s' is disabled", plugin.rdn)
def add_generic_plugin_parsers(subparser, plugin_cls):
diff --git a/src/lib389/lib389/cli_conf/backend.py b/src/lib389/lib389/cli_conf/backend.py
index c970e84..fdb5dd5 100644
--- a/src/lib389/lib389/cli_conf/backend.py
+++ b/src/lib389/lib389/cli_conf/backend.py
@@ -170,7 +170,7 @@ def backend_create(inst, basedn, log, args):
be = Backend(inst)
be.create(properties=props)
- print("The database was sucessfully created")
+ print("The database was successfully created")
def _recursively_del_backends(be):
@@ -197,7 +197,7 @@ def backend_delete(inst, basedn, log, args, warn=True):
_recursively_del_backends(be)
be.delete()
- print("The database, and any sub-suffixes, were sucessfully deleted")
+ print("The database, and any sub-suffixes, were successfully deleted")
def backend_import(inst, basedn, log, args):
@@ -307,7 +307,7 @@ def backend_set(inst, basedn, log, args):
be.enable()
if args.disable:
be.disable()
- print("The backend configuration was sucessfully updated")
+ print("The backend configuration was successfully updated")
def db_config_get(inst, basedn, log, args):
diff --git a/src/lib389/lib389/cli_conf/plugin.py b/src/lib389/lib389/cli_conf/plugin.py
index ea43a8d..5cc7c8c 100644
--- a/src/lib389/lib389/cli_conf/plugin.py
+++ b/src/lib389/lib389/cli_conf/plugin.py
@@ -13,6 +13,7 @@ from lib389.cli_base import (
_generic_get,
_get_arg,
)
+from lib389.cli_conf import generic_object_edit
from lib389.cli_conf.plugins import memberof as cli_memberof
from lib389.cli_conf.plugins import usn as cli_usn
from lib389.cli_conf.plugins import rootdn_ac as cli_rootdn_ac
@@ -31,6 +32,19 @@ SINGULAR = Plugin
MANY = Plugins
RDN = 'cn'
+arg_to_attr = {
+ 'initfunc': 'nsslapd-pluginInitfunc',
+ 'enabled': 'nsslapd-pluginEnabled',
+ 'path': 'nsslapd-pluginPath',
+ 'type': 'nsslapd-pluginType',
+ 'id': 'nsslapd-pluginId',
+ 'version': 'nsslapd-pluginVersion',
+ 'vendor': 'nsslapd-pluginVendor',
+ 'description': 'nsslapd-pluginDescription',
+ 'depends_on_type': 'nsslapd-plugin-depends-on-type',
+ 'depends_on_named': 'nsslapd-plugin-depends-on-named'
+}
+
def plugin_list(inst, basedn, log, args):
plugin_log = log.getChild('plugin_list')
@@ -77,25 +91,7 @@ def plugin_edit(inst, basedn, log, args):
rdn = _get_arg(args.selector, msg="Enter %s to retrieve" % RDN)
plugins = Plugins(inst)
plugin = plugins.get(rdn)
-
- if args.enabled is not None and args.enabled.lower() not in ["on", "off"]:
- raise ValueError("Plugin enabled argument should be 'on' or 'off'")
-
- plugin_args = {'nsslapd-pluginInitfunc': args.initfunc,
- 'nsslapd-pluginEnabled': args.enabled,
- 'nsslapd-pluginPath': args.path,
- 'nsslapd-pluginType': args.type,
- 'nsslapd-pluginId': args.id,
- 'nsslapd-pluginVersion': args.version,
- 'nsslapd-pluginVendor': args.vendor,
- 'nsslapd-pluginDescription': args.description}
- mods = vaidate_args(plugin, plugin_args)
-
- if len(mods) > 0:
- plugin.replace_many(*mods)
- log.info("Successfully changed the plugin %s", rdn)
- else:
- raise ValueError("Nothing to change")
+ generic_object_edit(plugin, log, args, arg_to_attr)
def create_parser(subparsers):
@@ -128,11 +124,17 @@ def create_parser(subparsers):
edit_parser.set_defaults(func=plugin_edit)
edit_parser.add_argument('selector', nargs='?', help='The plugin to edit')
edit_parser.add_argument('--type', help='The type of plugin.')
- edit_parser.add_argument('--enabled',
- help='Identifies whether or not the plugin is enabled. It should have "on" or "off" values.')
+ edit_parser.add_argument('--enabled', choices=['on', 'off'],
+ help='Identifies whether or not the plugin is enabled.')
edit_parser.add_argument('--path', help='The plugin library name (without the library suffix).')
edit_parser.add_argument('--initfunc', help='An initialization function of the plugin.')
edit_parser.add_argument('--id', help='The plugin ID.')
edit_parser.add_argument('--vendor', help='The vendor of plugin.')
edit_parser.add_argument('--version', help='The version of plugin.')
edit_parser.add_argument('--description', help='The description of the plugin.')
+ edit_parser.add_argument('--depends-on-type',
+ help='All plug-ins with a type value which matches one of the values '
+ 'in the following valid range will be started by the server prior to this plug-in.')
+ edit_parser.add_argument('--depends-on-named',
+ help='The plug-in name matching one of the following values will be '
+ 'started by the server prior to this plug-in')
diff --git a/src/lib389/lib389/cli_conf/plugins/memberof.py b/src/lib389/lib389/cli_conf/plugins/memberof.py
index b9865a8..0ccbed3 100644
--- a/src/lib389/lib389/cli_conf/plugins/memberof.py
+++ b/src/lib389/lib389/cli_conf/plugins/memberof.py
@@ -7,199 +7,92 @@
# --- END COPYRIGHT BLOCK ---
import ldap
-
-from lib389.plugins import MemberOfPlugin
-from lib389.cli_conf import add_generic_plugin_parsers
-
-
-def manage_attr(inst, basedn, log, args):
- if args.value is not None:
- set_attr(inst, basedn, log, args)
- else:
- display_attr(inst, basedn, log, args)
-
-def display_attr(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- log.info(plugin.get_attr_formatted())
-
-def set_attr(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- try:
- plugin.set_attr(args.value)
- except ldap.UNWILLING_TO_PERFORM:
- log.error('Error: Illegal value "{}". Failed to set.'.format(args.value))
- else:
- log.info('memberOfAttr set to "{}"'.format(args.value))
-
-def display_groupattr(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- log.info(plugin.get_groupattr_formatted())
-
-def add_groupattr(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- try:
- plugin.add_groupattr(args.value)
- except ldap.UNWILLING_TO_PERFORM:
- log.error('Error: Illegal value "{}". Failed to add.'.format(args.value))
- except ldap.TYPE_OR_VALUE_EXISTS:
- log.info('Value "{}" already exists.'.format(args.value))
- else:
- log.info('successfully added memberOfGroupAttr value "{}"'.format(args.value))
-
-def remove_groupattr(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- try:
- plugin.remove_groupattr(args.value)
- except ldap.UNWILLING_TO_PERFORM:
- log.error("Error: Failed to delete. memberOfGroupAttr is required.")
- except ldap.NO_SUCH_ATTRIBUTE:
- log.error('Error: Failed to delete. No value "{0}" found.'.format(args.value))
- else:
- log.info('successfully removed memberOfGroupAttr value "{}"'.format(args.value))
-
-def display_allbackends(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- val = plugin.get_allbackends_formatted()
- if not val:
- log.info("memberOfAllBackends is not set")
+from lib389.plugins import MemberOfPlugin, Plugins, MemberOfSharedConfig
+from lib389.cli_conf import add_generic_plugin_parsers, generic_object_edit, generic_object_add
+
+arg_to_attr = {
+ 'initfunc': 'nsslapd-pluginInitfunc',
+ 'attr': 'memberOfAttr',
+ 'groupattr': 'memberOfGroupAttr',
+ 'allbackends': 'memberOfAllBackends',
+ 'skipnested': 'memberOfSkipNested',
+ 'scope': 'memberOfEntryScope',
+ 'exclude': 'memberOfEntryScopeExcludeSubtree',
+ 'autoaddoc': 'memberOfAutoAddOC',
+ 'config_entry': 'nsslapd-pluginConfigArea'
+}
+
+
+def memberof_edit(inst, basedn, log, args):
+ log = log.getChild('memberof_edit')
+ plugins = Plugins(inst)
+ plugin = plugins.get("MemberOf Plugin")
+ generic_object_edit(plugin, log, args, arg_to_attr)
+
+
+def memberof_add_config(inst, basedn, log, args):
+ log = log.getChild('memberof_add_config')
+ targetdn = args.DN
+ config = MemberOfSharedConfig(inst, targetdn)
+ generic_object_add(config, log, args, arg_to_attr)
+ plugins = Plugins(inst)
+ plugin = plugins.get("MemberOf Plugin")
+ plugin.replace('nsslapd-pluginConfigArea', config.dn)
+ log.info('MemberOf attribute nsslapd-pluginConfigArea (config-entry) '
+ 'was set in the main plugin config')
+
+
+def memberof_edit_config(inst, basedn, log, args):
+ log = log.getChild('memberof_edit_config')
+ targetdn = args.DN
+ config = MemberOfSharedConfig(inst, targetdn)
+ generic_object_edit(config, log, args, arg_to_attr)
+
+
+def memberof_show_config(inst, basedn, log, args):
+ log = log.getChild('memberof_show_config')
+ targetdn = args.DN
+ config = MemberOfSharedConfig(inst, targetdn)
+
+ if not config.exists():
+ raise ldap.NO_SUCH_OBJECT("Entry %s doesn't exists" % targetdn)
+ if args and args.json:
+ o_str = config.get_all_attrs_json()
+ print(o_str)
else:
- log.info(val)
+ print(config.display())
-def enable_allbackends(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- plugin.enable_allbackends()
- log.info("memberOfAllBackends enabled successfully")
-
-def disable_allbackends(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- plugin.disable_allbackends()
- log.info("memberOfAllBackends disabled successfully")
-def display_skipnested(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- val = plugin.get_skipnested_formatted()
- if not val:
- log.info("memberOfSkipNested is not set")
- else:
- log.info(val)
-
-def enable_skipnested(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- plugin.enable_skipnested()
- log.info("memberOfSkipNested set successfully")
+def memberof_del_config(inst, basedn, log, args):
+ log = log.getChild('memberof_del_config')
+ targetdn = args.DN
+ config = MemberOfSharedConfig(inst, targetdn)
+ config.delete()
+ log.info("Successfully deleted the %s", targetdn)
-def disable_skipnested(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- plugin.disable_skipnested()
- log.info("memberOfSkipNested unset successfully")
-
-def manage_autoaddoc(inst, basedn, log, args):
- if args.value == "del":
- remove_autoaddoc(inst, basedn, log, args)
- elif args.value is not None:
- set_autoaddoc(inst, basedn, log, args)
- else:
- display_autoaddoc(inst, basedn, log, args)
-
-def display_autoaddoc(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- val = plugin.get_autoaddoc_formatted()
- if not val:
- log.info("memberOfAutoAddOc is not set")
- else:
- log.info(val)
-
-def set_autoaddoc(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- d = {'nsmemberof': 'nsMemberOf', 'inetuser': 'inetUser', 'inetadmin': 'inetAdmin'}
- plugin.set_autoaddoc(d[args.value])
- log.info('memberOfAutoAddOc set to "{}"'.format(d[args.value]))
-
-def remove_autoaddoc(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- if not plugin.get_autoaddoc():
- log.info("memberOfAutoAddOc was not set")
- else:
- plugin.remove_autoaddoc()
- log.info("memberOfAutoAddOc attribute deleted")
-
-def display_scope(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- val = plugin.get_entryscope_formatted()
- if not val:
- log.info("memberOfEntryScope is not set")
- else:
- log.info(val)
-
-def add_scope(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- try:
- plugin.add_entryscope(args.value)
- except ldap.UNWILLING_TO_PERFORM as ex:
- if "is also listed as an exclude suffix" in ex.args[0]['info']:
- log.error('Error: Include suffix ({0}) is also listed as an exclude suffix.'.format(args.value))
- else:
- log.error('Error: Invalid DN "{}". Failed to add.'.format(args.value))
- except ldap.TYPE_OR_VALUE_EXISTS:
- log.info('Value "{}" already exists.'.format(args.value))
- else:
- log.info('successfully added memberOfEntryScope value "{}"'.format(args.value))
-
-def remove_scope(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- try:
- plugin.remove_entryscope(args.value)
- except ldap.NO_SUCH_ATTRIBUTE:
- log.error('Error: Failed to delete. No value "{0}" found.'.format(args.value))
- else:
- log.info('successfully removed memberOfEntryScope value "{}"'.format(args.value))
-
-def remove_all_scope(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- plugin.remove_all_entryscope()
- log.info('successfully removed all memberOfEntryScope values')
-
-def display_excludescope(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- val = plugin.get_excludescope_formatted()
- if not val:
- log.info("memberOfEntryScopeExcludeSubtree is not set")
- else:
- log.info(val)
-
-def add_excludescope(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- try:
- plugin.add_excludescope(args.value)
- except ldap.UNWILLING_TO_PERFORM as ex:
- if "is also listed as an exclude suffix" in ex.args[0]['info']:
- log.error('Error: Suffix ({0}) is listed in entry scope.'.format(args.value))
- else:
- log.error('Error: Invalid DN "{}". Failed to add.'.format(args.value))
- except ldap.TYPE_OR_VALUE_EXISTS:
- log.info('Value "{}" already exists.'.format(args.value))
- else:
- log.info('successfully added memberOfEntryScopeExcludeSubtree value "{}"'.format(args.value))
-
-def remove_excludescope(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- try:
- plugin.remove_excludescope(args.value)
- except ldap.NO_SUCH_ATTRIBUTE:
- log.error('Error: Failed to delete. No value "{0}" found.'.format(args.value))
- else:
- log.info('successfully removed memberOfEntryScopeExcludeSubtree value "{}"'.format(args.value))
-
-def remove_all_excludescope(inst, basedn, log, args):
- plugin = MemberOfPlugin(inst)
- plugin.remove_all_excludescope()
- log.info('successfully removed all memberOfEntryScopeExcludeSubtree values')
def fixup(inst, basedn, log, args):
plugin = MemberOfPlugin(inst)
log.info('Attempting to add task entry... This will fail if MemberOf plug-in is not enabled.')
- fixup_task = plugin.fixup(args.basedn, args.filter)
- log.info('Successfully added task entry ' + fixup_task.dn)
+ assert plugin.status(), "'%s' is disabled. Fix up task can't be executed" % plugin.rdn
+ fixup_task = plugin.fixup(args.DN, args.filter)
+ fixup_task.wait()
+ exitcode = fixup_task.get_exit_code()
+ assert exitcode == 0, 'MemberOf fixup task for %s has failed. Please, check logs'
+ log.info('Successfully added task entry for %s', args.DN)
+
+
+def _add_parser_args(parser):
+ parser.add_argument('--attr', nargs='+', help='The value to set as memberOfAttr')
+ parser.add_argument('--groupattr', nargs='+', help='The value to set as memberOfGroupAttr')
+ parser.add_argument('--allbackends', choices=['on', 'off'], type=str.lower,
+ help='The value to set as memberOfAllBackends')
+ parser.add_argument('--skipnested', choices=['on', 'off'], type=str.lower,
+ help='The value to set as memberOfSkipNested')
+ parser.add_argument('--scope', help='The value to set as memberOfEntryScope')
+ parser.add_argument('--exclude', help='The value to set as memberOfEntryScopeExcludeSubtree')
+ parser.add_argument('--autoaddoc', type=str.lower, help='The value to set as memberOfAutoAddOC')
+
def create_parser(subparsers):
memberof_parser = subparsers.add_parser('memberof', help='Manage and configure MemberOf plugin')
@@ -208,69 +101,32 @@ def create_parser(subparsers):
add_generic_plugin_parsers(subcommands, MemberOfPlugin)
- attr_parser = subcommands.add_parser('attr', help='get or set memberofattr')
- attr_parser.set_defaults(func=manage_attr)
- attr_parser.add_argument('value', nargs='?', help='The value to set as memberofattr')
-
- groupattr_parser = subcommands.add_parser('groupattr', help='get or manage memberofgroupattr')
- groupattr_parser.set_defaults(func=display_groupattr)
- groupattr_subcommands = groupattr_parser.add_subparsers(help='action')
- add_groupattr_parser = groupattr_subcommands.add_parser('add', help='add memberofgroupattr value')
- add_groupattr_parser.set_defaults(func=add_groupattr)
- add_groupattr_parser.add_argument('value', help='The value to add in memberofgroupattr')
- del_groupattr_parser = groupattr_subcommands.add_parser('del', help='remove memberofgroupattr value')
- del_groupattr_parser.set_defaults(func=remove_groupattr)
- del_groupattr_parser.add_argument('value', help='The value to remove from memberofgroupattr')
-
- allbackends_parser = subcommands.add_parser('allbackends', help='get or manage memberofallbackends')
- allbackends_parser.set_defaults(func=display_allbackends)
- allbackends_subcommands = allbackends_parser.add_subparsers(help='action')
- on_allbackends_parser = allbackends_subcommands.add_parser('on', help='enable all backends for memberof')
- on_allbackends_parser.set_defaults(func=enable_allbackends)
- off_allbackends_parser = allbackends_subcommands.add_parser('off', help='disable all backends for memberof')
- off_allbackends_parser.set_defaults(func=disable_allbackends)
-
- skipnested_parser = subcommands.add_parser('skipnested', help='get or manage memberofskipnested')
- skipnested_parser.set_defaults(func=display_skipnested)
- skipnested_subcommands = skipnested_parser.add_subparsers(help='action')
- on_skipnested_parser = skipnested_subcommands.add_parser('on', help='skip nested groups for memberof')
- on_skipnested_parser.set_defaults(func=enable_skipnested)
- off_skipnested_parser = skipnested_subcommands.add_parser('off', help="don't skip nested groups for memberof")
- off_skipnested_parser.set_defaults(func=disable_skipnested)
-
- autoaddoc_parser = subcommands.add_parser('autoaddoc', help='get or set memberofautoaddoc')
- autoaddoc_parser.set_defaults(func=manage_autoaddoc)
- autoaddoc_parser.add_argument('value', nargs='?', choices=['nsmemberof', 'inetuser', 'inetadmin', 'del'],
- type=str.lower, help='The value to set as memberofautoaddoc or del to remove the attribute')
-
- scope_parser = subcommands.add_parser('scope', help='get or manage memberofentryscope')
- scope_parser.set_defaults(func=display_scope)
- scope_subcommands = scope_parser.add_subparsers(help='action')
- add_scope_parser = scope_subcommands.add_parser('add', help='add memberofentryscope value')
- add_scope_parser.set_defaults(func=add_scope)
- add_scope_parser.add_argument('value', help='The value to add in memberofentryscope')
- del_scope_parser = scope_subcommands.add_parser('del', help='remove memberofentryscope value')
- del_scope_parser.set_defaults(func=remove_scope)
- del_scope_parser.add_argument('value', help='The value to remove from memberofentryscope')
- delall_scope_parser = scope_subcommands.add_parser('delall', help='remove all memberofentryscope values')
- delall_scope_parser.set_defaults(func=remove_all_scope)
-
- exclude_parser = subcommands.add_parser('exclude', help='get or manage memberofentryscopeexcludesubtree')
- exclude_parser.set_defaults(func=display_excludescope)
- exclude_subcommands = exclude_parser.add_subparsers(help='action')
- add_exclude_parser = exclude_subcommands.add_parser('add', help='add memberofentryscopeexcludesubtree value')
- add_exclude_parser.set_defaults(func=add_excludescope)
- add_exclude_parser.add_argument('value', help='The value to add in memberofentryscopeexcludesubtree')
- del_exclude_parser = exclude_subcommands.add_parser('del', help='remove memberofentryscopeexcludesubtree value')
- del_exclude_parser.set_defaults(func=remove_excludescope)
- del_exclude_parser.add_argument('value', help='The value to remove from memberofentryscopeexcludesubtree')
- delall_exclude_parser = exclude_subcommands.add_parser('delall', help='remove all memberofentryscopeexcludesubtree values')
- delall_exclude_parser.set_defaults(func=remove_all_excludescope)
-
- fixup_parser = subcommands.add_parser('fixup', help='run the fix-up task for memberof plugin')
+ edit_parser = subcommands.add_parser('edit', help='Edit the plugin')
+ edit_parser.set_defaults(func=memberof_edit)
+ _add_parser_args(edit_parser)
+ edit_parser.add_argument('--config-entry', help='The value to set as nsslapd-pluginConfigArea')
+
+ config_parser = subcommands.add_parser('config-entry', help='Manage the config entry')
+ config_subcommands = config_parser.add_subparsers(help='action')
+ add_config_parser = config_subcommands.add_parser('add', help='Add the config entry')
+ add_config_parser.set_defaults(func=memberof_add_config)
+ add_config_parser.add_argument('DN', help='The config entry full DN')
+ _add_parser_args(add_config_parser)
+ edit_config_parser = config_subcommands.add_parser('edit', help='Edit the config entry')
+ edit_config_parser.set_defaults(func=memberof_edit_config)
+ edit_config_parser.add_argument('DN', help='The config entry full DN')
+ _add_parser_args(edit_config_parser)
+ show_config_parser = config_subcommands.add_parser('show', help='Display the config entry')
+ show_config_parser.set_defaults(func=memberof_show_config)
+ show_config_parser.add_argument('DN', help='The config entry full DN')
+ del_config_parser = config_subcommands.add_parser('delete', help='Delete the config entry')
+ del_config_parser.set_defaults(func=memberof_del_config)
+ del_config_parser.add_argument('DN', help='The config entry full DN')
+
+ fixup_parser = subcommands.add_parser('fixup', help='Run the fix-up task for memberOf plugin')
fixup_parser.set_defaults(func=fixup)
- fixup_parser.add_argument('-b', '--basedn', required=True, help="base DN that contains entries to fix up")
- fixup_parser.add_argument('-f', '--filter', help="Filter for entries to fix up.\n"
- "If omitted, all entries with objectclass inetuser/inetadmin/nsmemberof under the\n"
- "specified base will have their memberOf attribute regenerated."
- )
+ fixup_parser.add_argument('DN', help="base DN that contains entries to fix up")
+ fixup_parser.add_argument('-f', '--filter',
+ help='Filter for entries to fix up.\n If omitted, all entries with objectclass '
+ 'inetuser/inetadmin/nsmemberof under the specified base will have '
+ 'their memberOf attribute regenerated.')
diff --git a/src/lib389/lib389/cli_ctl/instance.py b/src/lib389/lib389/cli_ctl/instance.py
index ae17307..b70ec7c 100644
--- a/src/lib389/lib389/cli_ctl/instance.py
+++ b/src/lib389/lib389/cli_ctl/instance.py
@@ -68,7 +68,7 @@ def instance_create(inst, log, args):
sd = SetupDs(args.verbose, args.dryrun, log, args.containerised)
if sd.create_from_inf(args.file):
- # print("Sucessfully created instance")
+ # print("Successfully created instance")
return True
else:
# print("Failed to create instance")
@@ -200,6 +200,3 @@ def create_parser(subcommands):
remove_parser.set_defaults(func=instance_remove)
remove_parser.add_argument('--do-it', dest="ack", help="By default we do a dry run. This actually initiates the removal of the instance.",
action='store_true', default=False)
-
-
-
diff --git a/src/lib389/lib389/cli_idm/__init__.py b/src/lib389/lib389/cli_idm/__init__.py
index cb4fd11..fcf0175 100644
--- a/src/lib389/lib389/cli_idm/__init__.py
+++ b/src/lib389/lib389/cli_idm/__init__.py
@@ -107,13 +107,13 @@ def _generic_create(inst, basedn, log, manager_class, kwargs, args=None):
mc = manager_class(inst, basedn)
o = mc.create(properties=kwargs)
o_str = o.__unicode__()
- log.info('Sucessfully created %s' % o_str)
+ log.info('Successfully created %s' % o_str)
def _generic_delete(inst, basedn, log, object_class, dn, args=None):
# Load the oc direct
o = object_class(inst, dn)
o.delete()
- log.info('Sucessfully deleted %s' % dn)
+ log.info('Successfully deleted %s' % dn)
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/lib389/lib389/clitools/ds_setup b/src/lib389/lib389/clitools/ds_setup
index 212a34a..9e8b0d0 100755
--- a/src/lib389/lib389/clitools/ds_setup
+++ b/src/lib389/lib389/clitools/ds_setup
@@ -66,7 +66,7 @@ By setting this value you acknowledge and take responsibility for the fact this
print('Launching ...')
sd = SetupDs(args.verbose, args.dryrun)
if sd.create_from_inf(args.file):
- print("Sucessfully created instance")
+ print("Successfully created instance")
else:
print("Failed to create instance")
sys.exit(1)
@@ -75,4 +75,3 @@ By setting this value you acknowledge and take responsibility for the fact this
if __name__ == '__main__':
ds_setup_main()
-
diff --git a/src/lib389/lib389/replica.py b/src/lib389/lib389/replica.py
index cc695c7..a462c98 100644
--- a/src/lib389/lib389/replica.py
+++ b/src/lib389/lib389/replica.py
@@ -1073,15 +1073,15 @@ class Replica(DSLdapObject):
raise ValueError('Failed to update replica: ' + str(e))
elif replicarole == ReplicaRole.CONSUMER and newrole == ReplicaRole.MASTER:
try:
- self.apply_mods([(REPL_TYPE, str(REPLICA_RDWR_TYPE)),
- (REPL_FLAGS, str(REPLICA_FLAGS_WRITE)),
- (REPL_ID, str(rid))])
+ self.replace_many([(REPL_TYPE, str(REPLICA_RDWR_TYPE)),
+ (REPL_FLAGS, str(REPLICA_FLAGS_WRITE)),
+ (REPL_ID, str(rid))])
except ldap.LDAPError as e:
raise ValueError('Failed to update replica: ' + str(e))
elif replicarole == ReplicaRole.HUB and newrole == ReplicaRole.MASTER:
try:
- self.apply_mods([(REPL_TYPE, str(REPLICA_RDWR_TYPE)),
- (REPL_ID, str(rid))])
+ self.replace_many([(REPL_TYPE, str(REPLICA_RDWR_TYPE)),
+ (REPL_ID, str(rid))])
except ldap.LDAPError as e:
raise ValueError('Failed to update replica: ' + str(e))
@@ -1103,15 +1103,15 @@ class Replica(DSLdapObject):
# Demote it - set the replica type, flags and rid
if replicarole == ReplicaRole.MASTER and newrole == ReplicaRole.HUB:
try:
- self.apply_mods([(REPL_TYPE, str(REPLICA_RDONLY_TYPE)),
- (REPL_ID, str(CONSUMER_REPLICAID))])
+ self.replace_many([(REPL_TYPE, str(REPLICA_RDONLY_TYPE)),
+ (REPL_ID, str(CONSUMER_REPLICAID))])
except ldap.LDAPError as e:
raise ValueError('Failed to update replica: ' + str(e))
elif replicarole == ReplicaRole.MASTER and newrole == ReplicaRole.CONSUMER:
try:
- self.apply_mods([(REPL_TYPE, str(REPLICA_RDONLY_TYPE)),
- (REPL_FLAGS, str(REPLICA_FLAGS_RDONLY)),
- (REPL_ID, str(CONSUMER_REPLICAID))])
+ self.replace_many([(REPL_TYPE, str(REPLICA_RDONLY_TYPE)),
+ (REPL_FLAGS, str(REPLICA_FLAGS_RDONLY)),
+ (REPL_ID, str(CONSUMER_REPLICAID))])
except ldap.LDAPError as e:
raise ValueError('Failed to update replica: ' + str(e))
elif replicarole == ReplicaRole.HUB and newrole == ReplicaRole.CONSUMER:
diff --git a/src/lib389/lib389/tests/cli/conf_backend_test.py b/src/lib389/lib389/tests/cli/conf_backend_test.py
index 5043622..351d2bf 100644
--- a/src/lib389/lib389/tests/cli/conf_backend_test.py
+++ b/src/lib389/lib389/tests/cli/conf_backend_test.py
@@ -53,7 +53,7 @@ def create_backend(topology_st, request):
args.suffix = SUFFIX
backend_create(topology_st.standalone, None, None, args)
- check_output("The database was sucessfully created")
+ check_output("The database was successfully created")
def fin():
sys.stdout = io.StringIO()
@@ -66,7 +66,7 @@ def create_backend(topology_st, request):
# Delete backend
backend_delete(topology_st.standalone, None, None, args, warn=False)
- check_output("sucessfully deleted")
+ check_output("successfully deleted")
# Verify it's removed
args.suffix = False
@@ -137,7 +137,7 @@ def test_backend_cli(topology_st, create_backend):
args.suffix = SUB_SUFFIX
args.be_name = SUB_BE_NAME
backend_create(topology_st.standalone, None, topology_st.logcap.log, args)
- check_output("The database was sucessfully created")
+ check_output("The database was successfully created")
# Verify subsuffix
args.suffix = False
@@ -155,7 +155,7 @@ def test_backend_cli(topology_st, create_backend):
args.enable_readonly = True # Setting nsslapd-readonly to "on"
args.disable_readonly = False
backend_set(topology_st.standalone, None, topology_st.logcap.log, args)
- check_output("sucessfully updated")
+ check_output("successfully updated")
# Verify modified worked
args.selector = SUB_BE_NAME
@@ -165,7 +165,7 @@ def test_backend_cli(topology_st, create_backend):
# Delete subsuffix
args.suffix = SUB_SUFFIX
backend_delete(topology_st.standalone, None, topology_st.logcap.log, args, warn=False)
- check_output("sucessfully deleted")
+ check_output("successfully deleted")
# Verify it is deleted
args.suffix = False
@@ -175,7 +175,7 @@ def test_backend_cli(topology_st, create_backend):
# Modify backend (use same args from subsuffix modify)
args.be_name = BE_NAME
backend_set(topology_st.standalone, None, topology_st.logcap.log, args)
- check_output("sucessfully updated")
+ check_output("successfully updated")
# Verify modified worked
args.selector = BE_NAME
diff --git a/src/lib389/lib389/tests/cli/conf_chaining_test.py b/src/lib389/lib389/tests/cli/conf_chaining_test.py
index be19077..0b44770 100644
--- a/src/lib389/lib389/tests/cli/conf_chaining_test.py
+++ b/src/lib389/lib389/tests/cli/conf_chaining_test.py
@@ -46,7 +46,7 @@ def create_backend(topology_st, request):
args.create_entries = True
args.suffix = SUFFIX
backend_create(topology_st.standalone, None, None, args)
- check_output("The database was sucessfully created")
+ check_output("The database was successfully created")
def fin():
sys.stdout = io.StringIO()
@@ -60,7 +60,7 @@ def create_backend(topology_st, request):
# Delete backend
backend_delete(topology_st.standalone, None, None, args, warn=False)
- check_output("sucessfully deleted")
+ check_output("successfully deleted")
# Verify it's removed
args.suffix = False
diff --git a/src/lib389/lib389/tests/cli/idm_group_test.py b/src/lib389/lib389/tests/cli/idm_group_test.py
index 51ad85e..a9bf921 100644
--- a/src/lib389/lib389/tests/cli/idm_group_test.py
+++ b/src/lib389/lib389/tests/cli/idm_group_test.py
@@ -35,7 +35,7 @@ def test_group_tasks(topology):
topology.logcap.flush()
g_args.cn = 'testgroup'
create(topology.standalone, DEFAULT_SUFFIX, topology.logcap.log, g_args)
- assert(topology.logcap.contains("Sucessfully created testgroup"))
+ assert(topology.logcap.contains("Successfully created testgroup"))
# Assert it exists
topology.logcap.flush()
@@ -54,7 +54,7 @@ def test_group_tasks(topology):
u_args.uidNumber = '5000'
u_args.gidNumber = '5000'
create_user(topology.standalone, DEFAULT_SUFFIX, topology.logcap.log, u_args)
- assert(topology.logcap.contains("Sucessfully created testuser"))
+ assert(topology.logcap.contains("Successfully created testuser"))
# Add them to the group as a member
topology.logcap.flush()
@@ -86,5 +86,4 @@ def test_group_tasks(topology):
topology.logcap.flush()
g_args.dn = "cn=testgroup,ou=groups,dc=example,dc=com"
delete(topology.standalone, DEFAULT_SUFFIX, topology.logcap.log, g_args, warn=False)
- assert(topology.logcap.contains("Sucessfully deleted cn=testgroup,ou=groups,dc=example,dc=com"))
-
+ assert(topology.logcap.contains("Successfully deleted cn=testgroup,ou=groups,dc=example,dc=com"))
diff --git a/src/lib389/lib389/tests/cli/idm_user_test.py b/src/lib389/lib389/tests/cli/idm_user_test.py
index 42abd02..fdbc17d 100644
--- a/src/lib389/lib389/tests/cli/idm_user_test.py
+++ b/src/lib389/lib389/tests/cli/idm_user_test.py
@@ -52,7 +52,7 @@ def test_user_tasks(topology):
u_args.gidNumber = '5000'
create(topology.standalone, DEFAULT_SUFFIX, topology.logcap.log, u_args)
- assert(topology.logcap.contains("Sucessfully created testuser"))
+ assert(topology.logcap.contains("Successfully created testuser"))
# Assert they exist
topology.logcap.flush()
get(topology.standalone, DEFAULT_SUFFIX, topology.logcap.log, u_args)
@@ -82,9 +82,8 @@ def test_user_tasks(topology):
# Enroll a dummy sshkey
- # Delete it
+ # Delete it
topology.logcap.flush()
u_args.dn = 'uid=testuser,ou=people,dc=example,dc=com'
delete(topology.standalone, DEFAULT_SUFFIX, topology.logcap.log, u_args, warn=False)
- assert(topology.logcap.contains('Sucessfully deleted uid=testuser,ou=people,dc=example,dc=com'))
-
+ assert(topology.logcap.contains('Successfully deleted uid=testuser,ou=people,dc=example,dc=com'))
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 8 months
[389-ds-base] branch master updated: Bump version to 1.4.1.1
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch master
in repository 389-ds-base.
The following commit(s) were added to refs/heads/master by this push:
new af9bb72 Bump version to 1.4.1.1
af9bb72 is described below
commit af9bb7206aa39bb0c4c6fdbaa2653391f120671f
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Wed Jan 30 15:08:52 2019 -0500
Bump version to 1.4.1.1
---
VERSION.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/VERSION.sh b/VERSION.sh
index 2f8db57..4acdeb6 100644
--- a/VERSION.sh
+++ b/VERSION.sh
@@ -10,7 +10,7 @@ vendor="389 Project"
# PACKAGE_VERSION is constructed from these
VERSION_MAJOR=1
VERSION_MINOR=4
-VERSION_MAINT=1.0
+VERSION_MAINT=1.1
# NOTE: VERSION_PREREL is automatically set for builds made out of a git tree
VERSION_PREREL=
VERSION_DATE=$(date -u +%Y%m%d)
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 8 months
[389-ds-base] branch master updated: Bump version to 1.4.1.0
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch master
in repository 389-ds-base.
The following commit(s) were added to refs/heads/master by this push:
new abdf8aa Bump version to 1.4.1.0
abdf8aa is described below
commit abdf8aabdff76c0b671bd6a3503d86d99a581c42
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Thu Jan 24 12:01:02 2019 -0500
Bump version to 1.4.1.0
---
VERSION.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/VERSION.sh b/VERSION.sh
index 88330ee..2f8db57 100644
--- a/VERSION.sh
+++ b/VERSION.sh
@@ -10,7 +10,7 @@ vendor="389 Project"
# PACKAGE_VERSION is constructed from these
VERSION_MAJOR=1
VERSION_MINOR=4
-VERSION_MAINT=0.20
+VERSION_MAINT=1.0
# NOTE: VERSION_PREREL is automatically set for builds made out of a git tree
VERSION_PREREL=
VERSION_DATE=$(date -u +%Y%m%d)
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 8 months
[389-ds-base] 01/01: Merge #50079 `Fix for ticket 50059: If an object is nsds5replica, it must be cn=replica`
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
gparente pushed a commit to branch master
in repository 389-ds-base.
commit e08b20cc08fca684492276c2ecab456e054fca90
Merge: d23ef6d 7f3f978
Author: German Parente <gparente(a)redhat.com>
AuthorDate: Fri Jan 18 08:48:20 2019 +0000
Merge #50079 `Fix for ticket 50059: If an object is nsds5replica, it must be cn=replica`
.../plugins/replication/repl5_replica_config.c | 52 +++++++++++++++++++---
1 file changed, 46 insertions(+), 6 deletions(-)
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 8 months
[389-ds-base] branch master updated: Fix compiler warning in snmp main()
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch master
in repository 389-ds-base.
The following commit(s) were added to refs/heads/master by this push:
new e048503 Fix compiler warning in snmp main()
e048503 is described below
commit e0485033ec25c85f95129266dc9e3735b283abc7
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Tue Jan 15 14:40:39 2019 -0500
Fix compiler warning in snmp main()
Reviewed by: mreynolds(one line commit rule)
---
ldap/servers/snmp/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ldap/servers/snmp/main.c b/ldap/servers/snmp/main.c
index 1e64705..ccfb9b8 100644
--- a/ldap/servers/snmp/main.c
+++ b/ldap/servers/snmp/main.c
@@ -295,7 +295,7 @@ load_config(char *conf_path)
/* set pidfile path */
if ((pidfile = malloc(strlen(LOCALSTATEDIR) + strlen("/run/") +
strlen(LDAP_AGENT_PIDFILE) + 1)) != NULL) {
- strncpy(pidfile, LOCALSTATEDIR, strlen(LOCALSTATEDIR));
+ strncpy(pidfile, LOCALSTATEDIR, strlen(LOCALSTATEDIR) + 1);
/* The above will likely not be NULL terminated, but we need to
* be sure that we're properly NULL terminated for the below
* strcat() to work properly. */
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 8 months
[389-ds-base] branch master updated: Ticket - Fix compiler warning in init.c
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch master
in repository 389-ds-base.
The following commit(s) were added to refs/heads/master by this push:
new bf34aba Ticket - Fix compiler warning in init.c
bf34aba is described below
commit bf34abab1a6480329ed29ceb72eaa883668c08b3
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Tue Jan 15 14:06:51 2019 -0500
Ticket - Fix compiler warning in init.c
https://pagure.io/389-ds-base/issue/49574
Reviewed by: mreynolds(one line commit rule)
---
ldap/servers/slapd/back-ldbm/init.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/ldap/servers/slapd/back-ldbm/init.c b/ldap/servers/slapd/back-ldbm/init.c
index 73d7606..47a2b55 100644
--- a/ldap/servers/slapd/back-ldbm/init.c
+++ b/ldap/servers/slapd/back-ldbm/init.c
@@ -49,7 +49,6 @@ ldbm_back_init(Slapi_PBlock *pb)
struct ldbminfo *li;
int rc;
struct slapdplugin *p;
- static int interface_published = 0;
slapi_log_err(SLAPI_LOG_TRACE, "ldbm_back_init", "=>\n");
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 8 months
[389-ds-base] 02/02: Ticket 49540 - FIx compiler warning in ldif2ldbm
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.3.9
in repository 389-ds-base.
commit c9580477ffe22a08c0094378e81a6927d0dc4ffc
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Tue Jan 15 13:55:18 2019 -0500
Ticket 49540 - FIx compiler warning in ldif2ldbm
https://pagure.io/389-ds-base/issue/49540
Reviewed by: mreynolds(one line commit rule)
(cherry picked from commit 58be90b8bf96a7a0e10740b122035ea03fa13e0f)
---
ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index 69a2af9..11c020a 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -713,7 +713,7 @@ ldbm_back_ldif2ldbm(Slapi_PBlock *pb)
uint64_t refcnt;
refcnt = slapi_counter_get_value(inst->inst_ref_count);
if (refcnt > 0) {
- slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_ldif2ldbm", "ldbm: '%s' there are %d pending operation(s)."
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_ldif2ldbm", "ldbm: '%s' there are %" PRIu64 " pending operation(s)."
" Import can not proceed until they are completed.\n",
inst->inst_name,
refcnt);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 8 months
[389-ds-base] 01/02: Ticket 50117 - after certain failed import operation, impossible to replay an import operation
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.3.9
in repository 389-ds-base.
commit 630940ec119a90c3bbfc7cd3464eb02ab779b474
Author: Thierry Bordaz <tbordaz(a)redhat.com>
AuthorDate: Fri Jan 4 12:24:56 2019 +0100
Ticket 50117 - after certain failed import operation, impossible to replay an import operation
Bug Description:
At the beginning of an import, a flag is set to mark the target backend is busy.
Then import tests if there are pending operations. If such operations exist the import can not proceed and fails.
The problem is that in such case of pending operations, the import fails without resetting the busy flag.
It let the backend busy (until next reboot) and prevent new import.
Fix Description:
It needs to reset the busy flag if there are pending operations
https://pagure.io/389-ds-base/issue/50117
Reviewed by: Mark Reynolds, William Brown
Platforms tested: F27
Flag Day: no
Doc impact: no
(cherry picked from commit ff00b07402747aac403478a157adab75e306d7d1)
---
ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index 16b87ee..69a2af9 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -704,12 +704,22 @@ ldbm_back_ldif2ldbm(Slapi_PBlock *pb)
}
/* check if an import/restore is already ongoing... */
- if ((instance_set_busy(inst) != 0) ||
- (slapi_counter_get_value(inst->inst_ref_count) > 0)) {
+ if ((instance_set_busy(inst) != 0)) {
slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_ldif2ldbm", "ldbm: '%s' is already in the middle of "
"another task and cannot be disturbed.\n",
inst->inst_name);
return -1;
+ } else {
+ uint64_t refcnt;
+ refcnt = slapi_counter_get_value(inst->inst_ref_count);
+ if (refcnt > 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_ldif2ldbm", "ldbm: '%s' there are %d pending operation(s)."
+ " Import can not proceed until they are completed.\n",
+ inst->inst_name,
+ refcnt);
+ instance_set_not_busy(inst);
+ return -1;
+ }
}
if ((task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE)) {
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 8 months
[389-ds-base] branch master updated: Ticket 49540 - FIx compiler warning in ldif2ldbm
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch master
in repository 389-ds-base.
The following commit(s) were added to refs/heads/master by this push:
new 58be90b Ticket 49540 - FIx compiler warning in ldif2ldbm
58be90b is described below
commit 58be90b8bf96a7a0e10740b122035ea03fa13e0f
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Tue Jan 15 13:55:18 2019 -0500
Ticket 49540 - FIx compiler warning in ldif2ldbm
https://pagure.io/389-ds-base/issue/49540
Reviewed by: mreynolds(one line commit rule)
---
ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index b8052f9..a5c8c82 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -713,7 +713,7 @@ ldbm_back_ldif2ldbm(Slapi_PBlock *pb)
uint64_t refcnt;
refcnt = slapi_counter_get_value(inst->inst_ref_count);
if (refcnt > 0) {
- slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_ldif2ldbm", "ldbm: '%s' there are %d pending operation(s)."
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_ldif2ldbm", "ldbm: '%s' there are %" PRIu64 " pending operation(s)."
" Import can not proceed until they are completed.\n",
inst->inst_name,
refcnt);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
4 years, 8 months