← Back to team overview

cloud-init-dev team mailing list archive

[Merge] ~johnguthrie/cloud-init:instance_hostname_subst_for_chef into cloud-init:master

 

John Guthrie has proposed merging ~johnguthrie/cloud-init:instance_hostname_subst_for_chef into cloud-init:master.

Requested reviews:
  cloud-init commiters (cloud-init-dev)

For more details, see:
https://code.launchpad.net/~johnguthrie/cloud-init/+git/cloud-init/+merge/331905

Substitutions in cloud config data when using chef

In cloudinit/config/cc_puppet.py, the certname key will support substitutions for %i and %f.  This patch adds similar support for chef.  This patch adds two substitutions, %I and %i, that can each be used with the fqdn and node_name keys for chef.  %I can be used for the instance ID of the machine.  %i can be used for the "stripped" instance ID, that is the instance ID without an initial "i-".  The reasoning for this is so that people aren't forced to use hostnames like ntp-i-abcd1234, and instead can have a hostname like ntp-abcd1234.

I know that right now, this is a bit AWS-centric, but I hope to add some more intelligence to determine stripped instance IDs for use with other services.
-- 
Your team cloud-init commiters is requested to review the proposed merge of ~johnguthrie/cloud-init:instance_hostname_subst_for_chef into cloud-init:master.
diff --git a/cloudinit/config/cc_chef.py b/cloudinit/config/cc_chef.py
index 46abedd..7e4c9bd 100644
--- a/cloudinit/config/cc_chef.py
+++ b/cloudinit/config/cc_chef.py
@@ -23,6 +23,11 @@ chef will have forked into its own process) then a post run function can
 run that can do finishing activities (such as removing the validation pem
 file).
 
+The fqdn and node_name keys will support substitutions for ``%I`` and ``$i``.
+``%I`` is for the instance ID, and ``%i`` is for the stripped instance ID, that
+is the instance ID without the initial ``i-``.  (This is AWS specific for
+now.  Hopefully, this will improve over time.)
+
 **Internal name:** ``cc_chef``
 
 **Module frequency:** per always
@@ -229,6 +234,11 @@ def handle(name, cfg, cloud, log, _args):
             if k in CHEF_RB_TPL_PATH_KEYS and v:
                 param_paths.add(os.path.dirname(v))
         util.ensure_dirs(param_paths)
+        stripped_iid = iid.replace('i-','')
+        # expand %i
+        params['node_name'] = params['node_name'].replace("%i", stripped_iid)
+        # expand %I
+        params['node_name'] = params['node_name'].replace("%I", iid)
         templater.render_to_file(template_fn, CHEF_RB_PATH, params)
     else:
         log.warn("No template found, not rendering to %s",
diff --git a/cloudinit/util.py b/cloudinit/util.py
index e1290aa..b24e19e 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -1030,17 +1030,25 @@ def dos2unix(contents):
 
 
 def get_hostname_fqdn(cfg, cloud):
+    iid = cloud.get_instance_id()
+    stripped_iid = iid.replace('i-','')
+
     # return the hostname and fqdn from 'cfg'.  If not found in cfg,
     # then fall back to data from cloud
     if "fqdn" in cfg:
         # user specified a fqdn.  Default hostname then is based off that
         fqdn = cfg['fqdn']
+        # expand %I and %i
+        fqdn = fqdn.replace('%I',iid)
+        fqdn = fqdn.replace('%i',stripped_iid)
         hostname = get_cfg_option_str(cfg, "hostname", fqdn.split('.')[0])
     else:
         if "hostname" in cfg and cfg['hostname'].find('.') > 0:
             # user specified hostname, and it had '.' in it
             # be nice to them.  set fqdn and hostname from that
             fqdn = cfg['hostname']
+            fqdn = fqdn.replace('%I',iid)
+            fqdn = fqdn.replace('%i',stripped_iid)
             hostname = cfg['hostname'][:fqdn.find('.')]
         else:
             # no fqdn set, get fqdn from cloud.
@@ -1048,6 +1056,8 @@ def get_hostname_fqdn(cfg, cloud):
             fqdn = cloud.get_hostname(fqdn=True)
             if "hostname" in cfg:
                 hostname = cfg['hostname']
+                hostname = hostname.replace('%I',iid)
+                hostname = hostname.replace('%i',stripped_iid)
             else:
                 hostname = cloud.get_hostname()
     return (hostname, fqdn)

Follow ups