diff options
| -rw-r--r-- | ChangeLog | 1 | ||||
| -rw-r--r-- | cloudinit/CloudConfig/cc_phone_home.py | 82 | ||||
| -rw-r--r-- | doc/examples/cloud-config.txt | 14 | 
3 files changed, 86 insertions, 11 deletions
@@ -29,3 +29,4 @@     user_scripts to config_user_scripts   - add support for redirecting output of cloud-init, cloud-config, cloud-final     via the config file, or user data config file + - add support for posting data about the instance to a url (phone_home) diff --git a/cloudinit/CloudConfig/cc_phone_home.py b/cloudinit/CloudConfig/cc_phone_home.py index 89546287..ee463757 100644 --- a/cloudinit/CloudConfig/cc_phone_home.py +++ b/cloudinit/CloudConfig/cc_phone_home.py @@ -17,23 +17,83 @@  #    along with this program.  If not, see <http://www.gnu.org/licenses/>.  from cloudinit.CloudConfig import per_instance  import cloudinit.util as util +from time import sleep +  frequency = per_instance +post_list_all = [ 'pub_key_dsa', 'pub_key_rsa', 'instance_id', 'hostname' ] +# phone_home: +#  url: http://my.foo.bar/$INSTANCE/ +#  post: all +#  tries: 10 +# +# phone_home: +#  url: http://my.foo.bar/$INSTANCE_ID/ +#  post: [ pub_key_dsa, pub_key_rsa, instance_id +#     def handle(name,cfg,cloud,log,args):      if len(args) != 0: -        value = args[0] +        ph_cfg = util.readconf(args[0])      else: -        value = util.get_cfg_option_str(cfg,"phone_home_url",False) +        if not 'phone_home' in cfg: return +        ph_cfg = cfg['phone_home'] -    if not value: +    if 'url' not in ph_cfg: +        log.warn("no 'url' token in phone_home")          return -    # TODO: -    # implement phone_home -    # pass to it -    #  - ssh key fingerprints -    #  - mac addr ? -    #  - ip address -    #   -    log.warn("TODO: write cc_phone_home") +    url = ph_cfg['url'] +    post_list = ph_cfg.get('post', 'all') +    tries = ph_cfg.get('tries',10) +    try: +        tries = int(tries) +    except: +        log.warn("tries is not an integer. using 10") +        tries = 10 + +    if post_list == "all": +        post_list = post_list_all + +    all_keys = { } +    all_keys['instance_id'] = cloud.get_instance_id() +    all_keys['hostname'] = cloud.get_hostname() + +    pubkeys = { +        'pub_key_dsa': '/etc/ssh/ssh_host_dsa_key.pub', +        'pub_key_rsa': '/etc/ssh/ssh_host_rsa_key.pub', +    } + +    for n, path in pubkeys.iteritems(): +        try: +            fp = open(path, "rb") +            all_keys[n] = fp.read() +            all_keys[n] +            fp.close() +        except: +            log.warn("%s: failed to open in phone_home" % path) + +    submit_keys = { } +    for k in post_list: +        if k in all_keys: +            submit_keys[k] = all_keys[k] +        else: +            submit_keys[k] = "N/A" +            log.warn("requested key %s from 'post' list not available") + +    url = util.render_string(url, { 'INSTANCE_ID' : all_keys['instance_id'] }) + +    last_e = None +    for i in range(0,tries): +        try: +            util.readurl(url, submit_keys) +            log.debug("succeeded submit to %s on try %i" % (url, i+1)) +            return +        except Exception, e: +            log.debug("failed to post to %s on try %i" % (url, i+1)) +            last_e = e +        sleep(3) + +    log.warn("failed to post to %s in %i tries" % (url, tries)) +    if last_e: raise(last_e) +          return diff --git a/doc/examples/cloud-config.txt b/doc/examples/cloud-config.txt index a55670f6..1ba51243 100644 --- a/doc/examples/cloud-config.txt +++ b/doc/examples/cloud-config.txt @@ -310,3 +310,17 @@ output:   final:     output: "| tee /tmp/final.stdout | tee /tmp/bar.stdout"     error: "&1" + + +# phone_home: if this dictionary is present, then the phone_home +# cloud-config module will post specified data back to the given +# url +# default: none +# phone_home: +#  url: http://my.foo.bar/$INSTANCE/ +#  post: all +#  tries: 10 +# +phone_home: + url: http://my.example.com/$INSTANCE_ID/ + post: [ pub_key_dsa, pub_key_rsa, instance_id ]  | 
