← Back to team overview

cloud-init-dev team mailing list archive

[Merge] ~slystopad/cloud-init:merge/chpasswd-data-as-list into cloud-init:master

 

Serg Lystopad has proposed merging ~slystopad/cloud-init:merge/chpasswd-data-as-list into cloud-init:master.

Commit message:
Support data for chpasswd in list or string format.

By default cc_set_passwords supports list of pairs specified as multiline
string:

  chpasswd:
    list: |
      user:pass1
      user015:R

This patch adds support for user/pairs as yaml list:

chpasswd:
  list:
    - user:pass1
    - user015:R

LP: #1665773
LP: #1665694

Requested reviews:
  cloud init development team (cloud-init-dev)
  Server Team CI bot (server-team-bot): continuous-integration
Related bugs:
  Bug #1665694 in cloud-init: "cc_set_passwords fails to change passwords specified as chpasswd['list'] in cloud-config"
  https://bugs.launchpad.net/cloud-init/+bug/1665694
  Bug #1665773 in cloud-init: "wrong configuration example for cc_set_passwords module"
  https://bugs.launchpad.net/cloud-init/+bug/1665773

For more details, see:
https://code.launchpad.net/~slystopad/cloud-init/+git/cloud-init/+merge/319433
-- 
Your team cloud init development team is requested to review the proposed merge of ~slystopad/cloud-init:merge/chpasswd-data-as-list into cloud-init:master.
diff --git a/cloudinit/config/cc_set_passwords.py b/cloudinit/config/cc_set_passwords.py
index af6704c..301d5e9 100755
--- a/cloudinit/config/cc_set_passwords.py
+++ b/cloudinit/config/cc_set_passwords.py
@@ -50,6 +50,16 @@ enabled, disabled, or left to system defaults using ``ssh_pwauth``.
             user2:Random
             user3:password3
             user4:R
+
+    ##
+    # or as yaml list
+    ##
+    chpasswd:
+        list:
+            - user1:password1
+            - user2:Random
+            - user3:password3
+            - user4:R
 """
 
 import sys
@@ -79,7 +89,14 @@ def handle(_name, cfg, cloud, log, args):
 
     if 'chpasswd' in cfg:
         chfg = cfg['chpasswd']
-        plist = util.get_cfg_option_str(chfg, 'list', plist)
+        if isinstance(chfg['list'], list):
+            cfg_type = 'list'
+        else:
+            cfg_type = 'string'
+        if cfg_type == 'list':
+            plist = util.get_cfg_option_list(chfg, 'list', plist)
+        else:
+            plist = util.get_cfg_option_str(chfg, 'list', plist)
         expire = util.get_cfg_option_bool(chfg, 'expire', expire)
 
     if not plist and password:
@@ -95,13 +112,27 @@ def handle(_name, cfg, cloud, log, args):
         plist_in = []
         randlist = []
         users = []
-        for line in plist.splitlines():
+
+        def _prepare_credentials(line, **kwargs):
             u, p = line.split(':', 1)
             if p == "R" or p == "RANDOM":
                 p = rand_user_password()
-                randlist.append("%s:%s" % (u, p))
-            plist_in.append("%s:%s" % (u, p))
-            users.append(u)
+                kwargs['randlist'].append("%s:%s" % (u, p))
+            kwargs['plist_in'].append("%s:%s" % (u, p))
+            kwargs['users'].append(u)
+
+        if cfg_type == 'list':
+            log.warn("Handling input for chpasswd as list.")
+            for line in plist:
+                _prepare_credentials(line, randlist=randlist,
+                                     plist_in=plist_in,
+                                     users=users)
+        else:
+            log.warn("Handling input for chpasswd as multiline string.")
+            for line in plist.splitlines():
+                _prepare_credentials(line, randlist=randlist,
+                                     plist_in=plist_in,
+                                     users=users)
 
         ch_in = '\n'.join(plist_in) + '\n'
         try:

Follow ups