浏览代码

Ticket 49471 - Rename dscreate options

Description:  Changed the names of the two positional arguemnts from
              "fromfile" --> "install", and "example" --> "create-template"

              Added option for specifying template file instead
              of dumping the template to STDOUT

              Finally added autocomplete arg parsing to the cli tools,
              and used a unique file name in UI when creating template.

https://pagure.io/389-ds-base/issue/49791

Reviewed by: ?
Mark Reynolds 7 年之前
父节点
当前提交
749b9f3327

+ 15 - 14
rpm/389-ds-base.spec.in

@@ -286,6 +286,7 @@ Requires: python%{python3_pkgversion}-six
 Requires: python%{python3_pkgversion}-pyasn1
 Requires: python%{python3_pkgversion}-pyasn1-modules
 Requires: python%{python3_pkgversion}-dateutil
+Requires: python%{python3_pkgversion}-argcomplete
 %{?python_provide:%python_provide python%{python3_pkgversion}-lib389}
 %description -n python%{python3_pkgversion}-lib389
 This module contains tools and libraries for accessing, testing,
@@ -437,7 +438,7 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/libsvrcore.la
 
 
 %if %{use_perl}
-# make sure perl scripts have a proper shebang 
+# make sure perl scripts have a proper shebang
 sed -i -e 's|#{{PERL-EXEC}}|#!/usr/bin/perl|' $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/script-templates/template-*.pl
 %endif
 
@@ -573,7 +574,7 @@ for inst in $instances ; do
     echo restarting instance $inst >> $output 2>&1 || :
     /bin/systemctl start $inst >> $output 2>&1 || :
 done
-#END UPGRADE 
+#END UPGRADE
 %endif
 
 exit 0
@@ -960,7 +961,7 @@ exit 0
 - bump version to 1.3.0.rc3
 - Ticket 549 - DNA plugin no longer reports additional info when range is depleted
 - Ticket 541 - need to set plugin as off in ldif template
-- Ticket 541 - RootDN Access Control plugin is missing after upgrade 
+- Ticket 541 - RootDN Access Control plugin is missing after upgrade
 
 * Fri Dec 14 2012 Noriko Hosoi <[email protected]> - 1.3.0-0.2.rc2
 - bump version to 1.3.0.rc2
@@ -1028,16 +1029,16 @@ exit 0
 * Tue Oct 9 2012 Mark Reynolds <[email protected]> - 1.3.0.a1-1
 Ticket #28 	MOD operations with chained delete/add get back error 53 on backend config
 Ticket #173 	ds-logpipe.py script's man page and script help should be updated for -t option.
-Ticket #196 	RFE: Interpret IPV6 addresses for ACIs, replication, and chaining 
-Ticket #218 	RFE - Make RIP working with Replicated Entries 
-Ticket #328 	make sure all internal search filters are properly escaped 
+Ticket #196 	RFE: Interpret IPV6 addresses for ACIs, replication, and chaining
+Ticket #218 	RFE - Make RIP working with Replicated Entries
+Ticket #328 	make sure all internal search filters are properly escaped
 Ticket #329 	389-admin build fails on F-18 with new apache 	
 Ticket #344 	deadlock in replica_write_ruv
 Ticket #351 	use betxn plugins by default
-Ticket #352 	make cos, roles, views betxn aware 
+Ticket #352 	make cos, roles, views betxn aware
 Ticket #356 	logconv.pl - RFE - track bind info
-Ticket #365 	Audit log - clear text password in user changes 
-Ticket #370 	Opening merge qualifier CoS entry using RHDS console changes the entry. 
+Ticket #365 	Audit log - clear text password in user changes
+Ticket #370 	Opening merge qualifier CoS entry using RHDS console changes the entry.
 Ticket #372 	Setting nsslapd-listenhost or nsslapd-securelistenhost breaks ACI processing 	
 Ticket #386 	Overconsumption of memory with large cachememsize and heavy use of ldapmodify 	
 Ticket #402 	unhashedTicket #userTicket #password in entry extension 	
@@ -1568,7 +1569,7 @@ ice is restarted
 * Wed Mar  2 2011 Rich Megginson <[email protected]> - 1.2.8-0.6.rc1
 - 389-ds-base-1.2.8 release candidate 1 - git tag 389-ds-base-1.2.8.rc1
 - Bug 518890 - setup-ds-admin.pl - improve hostname validation
-- Bug 681015 - RFE: allow fine grained password policy duration attributes in 
+- Bug 681015 - RFE: allow fine grained password policy duration attributes in
 -     days, hours, minutes, as well
 - Bug 514190 - setup-ds-admin.pl --debug does not log to file
 - Bug 680555 - ns-slapd segfaults if I have more than 100 DBs
@@ -1621,12 +1622,12 @@ ice is restarted
 - Bug 151705 - Need to update Console Cipher Preferences with new ciphers
 - Bug 668862 - init scripts return wrong error code
 - Bug 670616 - Allow SSF to be set for local (ldapi) connections
-- Bug 667935 - DS pipe log script's logregex.py plugin is not redirecting the 
+- Bug 667935 - DS pipe log script's logregex.py plugin is not redirecting the
 -    log output to the text file
 - Bug 668619 - slapd stops responding
 - Bug 624547 - attrcrypt should query the given slot/token for
 -    supported ciphers
-- Bug 646381 - Faulty password for nsmultiplexorcredentials does not give any 
+- Bug 646381 - Faulty password for nsmultiplexorcredentials does not give any
 -    error message in logs
 
 * Fri Jan 21 2011 Nathan Kinder <[email protected]> - 1.2.8-0.1.a1
@@ -1685,7 +1686,7 @@ erral)
 
 * Mon Nov  1 2010 Rich Megginson <[email protected]> - 1.2.7-0.5.a4
 - 1.2.7.a4 release - git tag 389-ds-base-1.2.7.a4
-- Bug 647932 - multiple memberOf configuration adding memberOf where there is 
+- Bug 647932 - multiple memberOf configuration adding memberOf where there is
 no member
 - Bug 491733 - dbtest crashes
 - Bug 606545 - core schema should include numSubordinates
@@ -2030,7 +2031,7 @@ ions
 
 * Tue Jan 09 2007 Dennis Gilmore <[email protected]> - 1.1-0.1.cvs20070108
 - update to a cvs snapshot
-- fedorafy the spec 
+- fedorafy the spec
 - create -devel subpackage
 - apply a patch to use mozldap not mozldap6
 - apply a patch to allow --prefix to work correctly

+ 58 - 20
src/cockpit/389-console/js/servers.js

@@ -847,42 +847,80 @@ $(document).ready( function() {
         report_err($("#rootdn-pw"), 'Directory Manager passwords do not match!');
         $("#rootdn-pw-confirm").css("border-color", "red");
         return;
-      } else if (root_pw == "" || root_pw_confirm == ""){
+      } else if (root_pw == ""){
         report_err($("#rootdn-pw"), 'Directory Manager password can not be empty!');
         $("#rootdn-pw-confirm").css("border-color", "red");
         return;
       } else {
-        setup_inf = setup_inf.replace('ROOTPW', 'False');
+        setup_inf = setup_inf.replace('ROOTPW', root_pw);
       }
 
+      /*
+       * Here are steps we take to create the instance
+       *
+       * [1] Get FQDN Name for nsslapd-localhost setting in setup file
+       * [2] Create a file for the inf setup parameters
+       * [3] Set strict permissions on that file
+       * [4] Populate the new setup file with settings (including cleartext password)
+       * [5] Create the instance
+       * [6] Remove setup file
+       */
       cockpit.spawn(["hostname", "--fqdn"], { superuser: true, "err": "message" }).fail(function(ex) {
         // Failed to get FQDN
         popup_err("Failed to get hostname!", ex.message);
-
       }).done(function (data){
-        // Set the hostname in inf file
+        /* 
+         * We have FQDN, so set the hostname in inf file, and create the setup file
+         */
         setup_inf = setup_inf.replace('FQDN', data);
-
-        // Create setup inf file
-        var cmd = ["/bin/sh", "-c", '/usr/bin/echo -e "' + setup_inf + '" > /tmp/389setup.inf'];
-        cockpit.spawn(cmd, { superuser: true, "err": "message" }).fail(function(ex) {
+        var setup_file = "/tmp/389-setup-" + (new Date).getTime() + ".inf";
+        var rm_cmd = ['rm', setup_file];
+        var create_file_cmd = ['touch', setup_file];
+        cockpit.spawn(create_file_cmd, { superuser: true, "err": "message" }).fail(function(ex) {
+          // Failed to create setup file
           popup_err("Failed to create installation file!", ex.message);
         }).done(function (){
-          // Next, create the instance
-          cmd = ['dscreate', 'fromfile', '/tmp/389setup.inf'];
-          cockpit.spawn(cmd, { superuser: true, "err": "message" }).fail(function(ex) {
+          /*
+           * We have our new setup file, now set permissions on that setup file before we add sensitive data
+           */
+          var chmod_cmd = ['chmod', '600', setup_file];
+          cockpit.spawn(chmod_cmd, { superuser: true, "err": "message" }).fail(function(ex) {
+            // Failed to set permissions on setup file
+            cockpit.spawn(rm_cmd, { superuser: true });  // Remove Inf file with clear text password
             $("#create-inst-spinner").hide();
-            popup_err("Failed to create instance!", ex.message);
+            popup_err("Failed to set permission on setup file " + setup_file + ": ", ex.message);
           }).done(function (){
-            // Cleanup
-            $("#create-inst-spinner").hide();
-            $("#server-list-menu").attr('disabled', false); 
-            $("#no-instances").hide();
-            get_insts();  // Refresh server list
-            popup_msg("Success!", "Successfully created instance:  <b>slapd-" + new_server_id + "</b>", );
-            $("#create-inst-form").modal('toggle');
+            /*
+             * Success we have our setup file and it has the correct permissions.  
+             * Now populate the setup file...
+             */
+            var cmd = ["/bin/sh", "-c", '/usr/bin/echo -e "' + setup_inf + '" >> ' + setup_file];
+            cockpit.spawn(cmd, { superuser: true, "err": "message" }).fail(function(ex) {
+              // Failed to populate setup file
+              popup_err("Failed to populate installation file!", ex.message);
+            }).done(function (){
+              /* 
+               * Next, create the instance...
+               */
+              cmd = ['dscreate', 'install', setup_file];
+              cockpit.spawn(cmd, { superuser: true, "err": "message" }).fail(function(ex) {
+                // Failed to create the new instance!
+                cockpit.spawn(rm_cmd, { superuser: true });  // Remove Inf file with clear text password
+                $("#create-inst-spinner").hide();
+                popup_err("Failed to create instance!", ex.message);
+              }).done(function (){
+                // Success!!!  Now cleanup everything up...
+                cockpit.spawn(rm_cmd, { superuser: true });  // Remove Inf file with clear text password
+                $("#create-inst-spinner").hide();
+                $("#server-list-menu").attr('disabled', false); 
+                $("#no-instances").hide();
+                get_insts();  // Refresh server list
+                popup_msg("Success!", "Successfully created instance:  <b>slapd-" + new_server_id + "</b>", );
+                $("#create-inst-form").modal('toggle');
+              });
+            }); 
+            $("#create-inst-spinner").show();
           });
-          $("#create-inst-spinner").show();
         });
       });
     });

+ 4 - 3
src/lib389/cli/dsconf

@@ -7,8 +7,10 @@
 # License: GPL (version 3 or any later version).
 # See LICENSE for details.
 # --- END COPYRIGHT BLOCK ---
+#
+# PYTHON_ARGCOMPLETE_OK
 
-import argparse
+import argparse, argcomplete
 import logging
 import ldap
 import sys
@@ -84,7 +86,7 @@ if __name__ == '__main__':
     cli_whoami.create_parser(subparsers)
     cli_referint.create_parser(subparsers)
     cli_automember.create_parser(subparsers)
-
+    argcomplete.autocomplete(parser)
     args = parser.parse_args()
 
     log = reset_get_logger('dsconf', args.verbose)
@@ -98,7 +100,6 @@ if __name__ == '__main__':
     dsrc_inst = dsrc_to_ldap("~/.dsrc", args.instance, log.getChild('dsrc'))
 
     # Now combine this with our arguments
-
     dsrc_inst = dsrc_arg_concat(args, dsrc_inst)
 
     log.debug("Called with: %s" % args)

+ 14 - 10
src/lib389/cli/dscreate

@@ -1,14 +1,16 @@
 #!/usr/bin/python3
 
 # --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2016 Red Hat, Inc.
+# Copyright (C) 2018 Red Hat, Inc.
 # All rights reserved.
 #
 # License: GPL (version 3 or any later version).
 # See LICENSE for details.
 # --- END COPYRIGHT BLOCK ---
+#
+# PYTHON_ARGCOMPLETE_OK
 
-import argparse
+import argparse, argcomplete
 import logging
 import sys
 
@@ -27,22 +29,24 @@ if __name__ == '__main__':
 
     subparsers = parser.add_subparsers(help="action")
 
-    fromfile_parser = subparsers.add_parser('fromfile', help="Create an instance of Directory Server from an inf answer file")
-    fromfile_parser.add_argument('file', help="Inf file to use with prepared answers. You can generate an example of this with 'dscreate example'")
-    fromfile_parser.add_argument('-n', '--dryrun', help="Validate system and configurations only. Do not alter the system.",
+    install_parser = subparsers.add_parser('install', help="Create an instance of Directory Server from an inf answer file")
+    install_parser.add_argument('file', help="Inf file to use with prepared answers. You can generate an example of this with 'dscreate create-template'")
+    install_parser.add_argument('-n', '--dryrun', help="Validate system and configurations only. Do not alter the system.",
                                  action='store_true', default=False)
-    fromfile_parser.add_argument('--IsolemnlyswearthatIamuptonogood', dest="ack",
+    install_parser.add_argument('--IsolemnlyswearthatIamuptonogood', dest="ack",
                                  help="""You are here likely here by mistake! You want setup-ds.pl!
 By setting this value you acknowledge and take responsibility for the fact this command is UNTESTED and NOT READY. You are ON YOUR OWN!
 """,
                                  action='store_true', default=False)
-    fromfile_parser.add_argument('-c', '--containerised', help="Indicate to the installer that this is running in a container. Used to disable systemd native components, even if they are installed.",
+    install_parser.add_argument('-c', '--containerised', help="Indicate to the installer that this is running in a container. Used to disable systemd native components, even if they are installed.",
                                  action='store_true', default=False)
-    fromfile_parser.set_defaults(func=cli_instance.instance_create)
+    install_parser.set_defaults(func=cli_instance.instance_create)
 
-    example_parser = subparsers.add_parser('example', help="Display an example ini answer file, with comments")
-    example_parser.set_defaults(func=cli_instance.instance_example)
+    template_parser = subparsers.add_parser('create-template', help="Display an example inf answer file, or provide a file name to write it to disk.")
+    template_parser.add_argument('template_file', nargs="?", default=None, help="Write example template to this file")
+    template_parser.set_defaults(func=cli_instance.instance_example)
 
+    argcomplete.autocomplete(parser)
     args = parser.parse_args()
 
     log = reset_get_logger("dscreate", args.verbose)

+ 4 - 2
src/lib389/cli/dsctl

@@ -7,8 +7,10 @@
 # License: GPL (version 3 or any later version).
 # See LICENSE for details.
 # --- END COPYRIGHT BLOCK ---
+#
+# PYTHON_ARGCOMPLETE_OK
 
-import argparse
+import argparse, argcomplete
 import logging
 import sys
 
@@ -36,8 +38,8 @@ if __name__ == '__main__':
             help="Return result in JSON object",
             default=False, action='store_true'
         )
-
     subparsers = parser.add_subparsers(help="action")
+    argcomplete.autocomplete(parser)
 
     # We stack our needed options in via submodules.
 

+ 4 - 3
src/lib389/cli/dsidm

@@ -7,10 +7,11 @@
 # License: GPL (version 3 or any later version).
 # See LICENSE for details.
 # --- END COPYRIGHT BLOCK ---
+#
+# PYTHON_ARGCOMPLETE_OK
 
 import ldap
-import argparse
-# import argcomplete
+import argparse, argcomplete
 import logging
 import sys
 
@@ -70,8 +71,8 @@ if __name__ == '__main__':
     cli_ou.create_parser(subparsers)
     cli_posixgroup.create_parser(subparsers)
     cli_user.create_parser(subparsers)
+    argcomplete.autocomplete(parser)
 
-    # argcomplete.autocomplete(parser)
     args = parser.parse_args()
 
     log = reset_get_logger('dsidm', args.verbose)

+ 24 - 8
src/lib389/lib389/cli_ctl/instance.py

@@ -1,5 +1,5 @@
 # --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2016 Red Hat, Inc.
+# Copyright (C) 2018 Red Hat, Inc.
 # All rights reserved.
 #
 # License: GPL (version 3 or any later version).
@@ -66,17 +66,15 @@ def instance_create(inst, log, args):
 
 
 def instance_example(inst, log, args):
-    print("""
+    gpl_copyright = """
 ; --- BEGIN COPYRIGHT BLOCK ---
-; Copyright (C) 2015 Red Hat, Inc.
+; Copyright (C) 2018 Red Hat, Inc.
 ; All rights reserved.
 ;
 ; License: GPL (version 3 or any later version).
 ; See LICENSE for details.
 ; --- END COPYRIGHT BLOCK ---
 
-; Author: firstyear at redhat.com
-
 ; This is a version 2 ds setup inf file.
 ; It is used by the python versions of setup-ds-*
 ; Most options map 1 to 1 to the original .inf file.
@@ -87,11 +85,29 @@ def instance_example(inst, log, args):
 ; The special value {instance_name} is substituted at installation time.
 ;
 
-    """)
+    """
     g2b = General2Base(log)
     s2b = Slapd2Base(log)
-    print(g2b.collect_help())
-    print(s2b.collect_help())
+    if args.template_file:
+        try:
+            # Create file and set permissions
+            template_file = open(args.template_file, 'w')
+            template_file.close()
+            os.chmod(args.template_file, 0o600)
+
+            # Open file and populate it
+            template_file = open(args.template_file, 'w')
+            template_file.write(gpl_copyright)
+            template_file.write(g2b.collect_help())
+            template_file.write(s2b.collect_help())
+            template_file.close()
+        except OSError as e:
+            log.error("Failed trying to create template file ({}), error: {}".format(args.template_file, str(e)))
+            return False
+    else:
+        print(gpl_copyright)
+        print(g2b.collect_help())
+        print(s2b.collect_help())
     return True