github.com/greenboxal/deis@v1.12.1/contrib/linode/create-linode-user-data.py (about)

     1  #!/usr/bin/env python
     2  """
     3  Create CoreOS user-data by merging contrib/coreos/user-data and contrib/linode/linode-user-data-template
     4  
     5  Usage: create-linode-user-data.py
     6  """
     7  import base64
     8  import sys
     9  import os
    10  import collections
    11  import argparse
    12  
    13  import yaml
    14  import colorama
    15  from colorama import Fore, Style
    16  import requests
    17  
    18  
    19  def combine_dicts(orig_dict, new_dict):
    20      for key, val in new_dict.iteritems():
    21          if isinstance(val, collections.Mapping):
    22              tmp = combine_dicts(orig_dict.get(key, {}), val)
    23              orig_dict[key] = tmp
    24          elif isinstance(val, list):
    25              orig_dict[key] = (orig_dict.get(key, []) + val)
    26          else:
    27              orig_dict[key] = new_dict[key]
    28      return orig_dict
    29  
    30  
    31  def get_file(name, mode="r", abspath=False):
    32      current_dir = os.path.dirname(__file__)
    33  
    34      if abspath:
    35          return file(os.path.abspath(os.path.join(current_dir, name)), mode)
    36      else:
    37          return file(os.path.join(current_dir, name), mode)
    38  
    39  
    40  def main():
    41      colorama.init()
    42  
    43      parser = argparse.ArgumentParser(description='Create Linode User Data')
    44      parser.add_argument('--public-key', action='append', required=True, type=file, dest='public_key_files', help='Authorized SSH Keys')
    45      parser.add_argument('--etcd-token', required=False, default=None, dest='etcd_token', help='Etcd Token')
    46      args = parser.parse_args()
    47  
    48      etcd_token = args.etcd_token
    49      if etcd_token is None:
    50          etcd_token = generate_etcd_token()
    51      else:
    52          if not validate_etcd_token(args.etcd_token):
    53              raise ValueError('Invalid Etcd Token. You can generate a new token at https://discovery.etcd.io/new.')
    54  
    55      public_keys = []
    56      for public_key_file in args.public_key_files:
    57          public_key = public_key_file.read()
    58          if validate_public_key(public_key):
    59              public_keys.append(public_key)
    60          else:
    61              log_warning('Invalid public key: ' + public_key_file.name)
    62  
    63      if not len(public_keys) > 0:
    64          raise ValueError('Must supply at least one valid public key')
    65  
    66      linode_user_data = get_file("linode-user-data.yaml", "w", True)
    67      linode_template = get_file("linode-user-data-template.yaml")
    68      coreos_template = get_file("../coreos/user-data.example")
    69  
    70      coreos_template_string = coreos_template.read()
    71      coreos_template_string = coreos_template_string.replace('#DISCOVERY_URL', 'https://discovery.etcd.io/' + str(etcd_token))
    72  
    73      configuration_linode_template = yaml.safe_load(linode_template)
    74      configuration_coreos_template = yaml.safe_load(coreos_template_string)
    75  
    76      configuration = combine_dicts(configuration_coreos_template, configuration_linode_template)
    77      configuration['ssh_authorized_keys'] = public_keys
    78  
    79      dump = yaml.dump(configuration, default_flow_style=False, default_style='|')
    80  
    81      with linode_user_data as outfile:
    82          outfile.write("#cloud-config\n\n" + dump)
    83          log_success('Wrote Linode user data to ' + linode_user_data.name)
    84  
    85  
    86  def validate_public_key(key):
    87      try:
    88          type, key_string, comment = key.split()
    89          data = base64.decodestring(key_string)
    90          return data[4:11] == type
    91      except:
    92          return False
    93  
    94  
    95  def generate_etcd_token():
    96      log_info('Generating new Etcd token...')
    97      data = requests.get('https://discovery.etcd.io/new').text
    98      token = data.replace('https://discovery.etcd.io/', '')
    99      log_success('Generated new token: ' + token)
   100      return token
   101  
   102  
   103  def validate_etcd_token(token):
   104      try:
   105          int(token, 16)
   106          return True
   107      except:
   108          return False
   109  
   110  
   111  def log_info(message):
   112      print(Fore.CYAN + message + Fore.RESET)
   113  
   114  
   115  def log_warning(message):
   116      print(Fore.YELLOW + message + Fore.RESET)
   117  
   118  
   119  def log_success(message):
   120      print(Style.BRIGHT + Fore.GREEN + message + Fore.RESET + Style.RESET_ALL)
   121  
   122  
   123  def log_error(message):
   124      print(Style.BRIGHT + Fore.RED + message + Fore.RESET + Style.RESET_ALL)
   125  
   126  
   127  if __name__ == "__main__":
   128      try:
   129          main()
   130      except Exception as e:
   131          log_error(e.message)
   132          sys.exit(1)