Ejemplo n.º 1
0
 def import_file(self, import_file_path=None):
     skipped = 0
     invalid_count = 0
     if is_readable(import_file_path):
         import_entries = []
         with open(import_file_path, "r") as infile:
             for line in infile:
                 stripped_entry = line.strip()
                 if (not stripped_entry) or (stripped_entry.startswith("#")):
                     skipped += 1
                 else:
                     line = line.partition("#")[0]
                     line = line.rstrip()
                     import_entry = HostsEntry.str_to_hostentry(line)
                     if import_entry:
                         import_entries.append(import_entry)
                     else:
                         invalid_count += 1
         add_result = self.add(entries=import_entries)
         write_result = self.write()
         return {
             "result": "success",
             "skipped": skipped,
             "invalid_count": invalid_count,
             "add_result": add_result,
             "write_result": write_result,
         }
     else:
         return {
             "result": "failed",
             "message": "Cannot read: file {0}.".format(import_file_path),
         }
Ejemplo n.º 2
0
 def get_user_data_from_file(self):
     file_name = self.lc_config.cloud_init
     if not file_name:
         return None
     if not utils.is_readable(file_name):
         print_msg("Can't open cloud-init file %s for reading" %
                   file_name, bcolors.FAIL)
     return open(file_name, 'r').read()
Ejemplo n.º 3
0
    def validate(self):
        """ Iterates over class attributes and verifies that they have been set
        during the config parsing or config writing process
        """

        ok_missing = ['user_data', 'networks']
        for obj in [
                obj for obj in dir(self)
                if not obj.startswith('__') and obj not in ok_missing
        ]:
            if getattr(self, obj) is None:
                raise AttributeError("Config file parsing failed - key %s"
                                     " is missing or has no value in section"
                                     " 'launch-configuration'"
                                     " Try re-running with --create-config" %
                                     obj)

        if not isinstance(self.metadata, dict):
            raise AttributeError(
                utils.get_parse_error('metadata', 'launch-configuration',
                                      'dictionary'))
        if not isinstance(self.image, str):
            raise AttributeError(
                utils.get_parse_error('image', 'launch-configuration',
                                      'string'))

        if not isinstance(self.networks, list):
            raise AttributeError(
                utils.get_parse_error('networks', 'launch-configuration',
                                      'list'))

        if not isinstance(self.skip_default_networks, bool):
            raise AttributeError(
                utils.get_parse_error('skip_default_networks',
                                      'launch-configuration', 'boolean'))

        if self.cloud_init and self.cloud_init is not '':
            if not utils.is_readable(self.cloud_init):
                raise AttributeError("Config file validation failed cloud_init"
                                     " file not readable")
            self.config_drive = True
        else:
            self.cloud_init = None
        return True
Ejemplo n.º 4
0
    def validate(self):
        """ Iterates over class attributes and verifies that they have been set
        during the config parsing or config writing process
        """

        ok_missing = ['user_data', 'networks']
        for obj in [obj for obj in dir(self) if not
                    obj.startswith('__') and obj not in ok_missing]:
            if getattr(self, obj) is None:
                raise AttributeError("Config file parsing failed - key %s"
                                     " is missing or has no value in section"
                                     " 'launch-configuration'"
                                     " Try re-running with --create-config" %
                                     obj)

        if not isinstance(self.metadata, dict):
            raise AttributeError(utils.get_parse_error('metadata',
                                                       'launch-configuration',
                                                       'dictionary'))
        if not isinstance(self.image, str):
            raise AttributeError(utils.get_parse_error('image',
                                                       'launch-configuration',
                                                       'string'))

        if not isinstance(self.networks, list):
            raise AttributeError(utils.get_parse_error('networks',
                                                       'launch-configuration',
                                                       'list'))

        if not isinstance(self.skip_default_networks, bool):
            raise AttributeError(utils.get_parse_error('skip_default_networks',
                                                       'launch-configuration',
                                                       'boolean'))

        if self.cloud_init and self.cloud_init is not '':
            if not utils.is_readable(self.cloud_init):
                raise AttributeError(
                    "Config file validation failed cloud_init"
                    " file not readable")
            self.config_drive = True
        else:
            self.cloud_init = None
        return True
Ejemplo n.º 5
0
def write_config(config, pyrax):
    """ Prompt for missing keys in the config file and writes a new one out """

    config.parse_config()
    try:
        if config.lc_config.validate() and \
           config.as_config.validate() and \
           config.as_config.id:
            utils.print_msg(
                "Config defined in %s passes validation."
                " Checking for misconfiguration and missing"
                " optional keys.." % (config.config_file), bcolors.OKGREEN)
    except AttributeError:
        pass

    ##
    # Write [autoscale] config
    ##
    if not config.as_config.id:
        group = utils.get_object_from_list(pyrax.autoscale,
                                           "group",
                                           create_new_option=True)
        if group is not None:
            config.set_config_option('autoscale', 'id', group)

    if not config.as_config.name:
        group_name = utils.ask_str("Name of autoscale_group: ")
        config.set_config_option('autoscale', 'name', group_name)

    if not isinstance(config.as_config.scale_up, int):
        scale_up = utils.ask_integer(
            "Number of servers to scale up by when triggered: ")
        config.set_config_option('autoscale', 'scale_up', scale_up)

    if not isinstance(config.as_config.scale_down, int):
        scale_down = utils.ask_integer(
            "Number of servers to scale down by when triggered: ")
        config.set_config_option('autoscale', 'scale_down', scale_down)

    if not isinstance(config.as_config.max_entities, int):
        max_entities = utils.ask_integer(
            "Max number of servers to scale up to (max_entities): ")
        config.set_config_option('autoscale', 'max_entities', max_entities)

    if not isinstance(config.as_config.min_entities, int):
        max_entities = config.as_config.max_entities
        min_entities = utils.ask_integer(
            "Never scale down below this number of servers (min_entities): ")
        if min_entities > max_entities:
            print_msg(
                "min_entities must be smaller than or equal"
                "to max_entities (%d)" % max_entities, bcolors.FAIL)
            min_entities = utils.ask_integer(
                "Never scale down below this "
                "number of servers"
                " (min_entities): ",
                allowed_input=xrange(0, max_entities))
        config.set_config_option('autoscale', 'min_entities', min_entities)
    if not isinstance(config.as_config.cooldown, int):
        cooldown = utils.ask_integer(
            "Do not process scale event more frequent than"
            " this (cooldown, seconds): ")
        config.set_config_option('autoscale', 'cooldown', cooldown)

    ##
    # Write [launch-config] config
    ##
    if not config.lc_config.image:
        image = utils.get_object_from_list(pyrax.images, "image")
        config.set_config_option('launch-configuration', 'image', image)

    if not config.lc_config.flavor:
        flavor = utils.get_object_from_list(pyrax.cloudservers.flavors,
                                            "flavor")
        config.set_config_option('launch-configuration', 'flavor', flavor)

    if not config.lc_config.key_name:
        key_name = utils.get_object_from_list(pyrax.cloudservers.keypairs,
                                              "ssh-key to add to"
                                              " /root/.ssh/authorized_keys on"
                                              " the servers",
                                              create_new_option=True)
        if key_name is None:
            key_name = utils.add_new_key(pyrax)
        config.set_config_option('launch-configuration', 'key_name', key_name)

    if not config.lc_config.name:
        name = utils.ask_str("Server name (note that an 11 character suffix"
                             " will be added to this name): ")
        config.set_config_option('launch-configuration', 'name', name)

    if config.get('launch-configuration', 'cloud_init') is None:
        print("When servers are booted up, the contents of the cloud-init"
              " script will be executed on the server. This is a way to"
              " install and configure the software the machine needs"
              " in order to serve its purpose.\n"
              "To use the default - input: templates/cloud-init.yml.j2")
        cloud_init = utils.ask_file("Path to cloud-init script: ")
        config.set_config_option('launch-configuration', 'cloud_init',
                                 cloud_init)

    if not isinstance(config.lc_config.networks, list):
        networks = []
        utils.print_msg(
            "Supply one or more networks you wish to"
            "attach the cloud servers to", bcolors.QUESTION)
        while True:
            network = utils.get_object_from_list(pyrax.cloud_networks,
                                                 "network",
                                                 quit_option=True)
            if network and network not in networks:
                networks.append(str(network))
            elif network:
                pass
            else:
                break
        config.set_config_option('launch-configuration', 'networks', networks)

    if not config.get('launch-configuration', 'skip_default_networks'):
        print("By default, the launch config will contain the default"
              " networks (PublicNet and ServiceNet). You can optionally"
              " disable these, but some Rackspace services will not function"
              " properly without them, and they are obligatory on Managed"
              " service levels")
        keep = utils.ask_str("Keep default networks? (y/n): ", yesno=True)
        if keep:
            config.set_config_option('launch-configuration',
                                     'skip_default_networks', False)
        else:
            config.set_config_option('launch-configuration',
                                     'skip_default_networks', True)

    if not config.get('launch-configuration', 'disk_config'):
        disk_config = utils.ask_str(
            "Disk config method (AUTO or MANUAL): ",
            allowed_input=['AUTO', 'MANUAL', 'auto', 'manual'])
        config.set_config_option('launch-configuration', 'disk_config',
                                 disk_config.upper())

    ##
    # Write [rax-autoscaler] config
    ##

    if not isinstance(config.ras_config.load_balancers, list):
        load_balancers = []
        utils.print_msg(
            "Supply one or more load balancers you wish to"
            " attach the cloud servers to", bcolors.QUESTION)
        while True:
            load_balancer = utils.get_object_from_list(
                pyrax.cloud_loadbalancers, "load balancer", quit_option=True)
            if load_balancer and load_balancer not in load_balancers:
                load_balancers.append(load_balancer)
            elif load_balancer:
                pass
            else:
                break
        config.set_config_option('rax-autoscaler', 'load_balancers',
                                 load_balancers)

    if not isinstance(config.ras_config.num_static_servers, int):
        num_static_servers = utils.ask_integer(
            "How many nodes in the load balancer are"
            " not part of the scaling group? (0 for none): ")
        config.set_config_option('rax-autoscaler', 'num_static_servers',
                                 num_static_servers)

    if not isinstance(config.ras_config.private_key, str) or \
       not utils.is_readable(config.ras_config.private_key):
        print("When scaled up, the servers need to log in to the admin server"
              " in order to download the playbook, or perform other tasks as"
              " laid out in the cloud-init template.\nSupply a private key"
              " which can be used to log in as the user 'autoscale' on the"
              " admin server")
        private_key = utils.ask_file("Private key to inject"
                                     " into /root/.ssh/id_rsa on servers: ")
        config.set_config_option('rax-autoscaler', 'private_key', private_key)

    if not isinstance(config.ras_config.admin_server, str):
        admin_server = utils.ask_str("IP or host-name of admin server to"
                                     " download playbook from: ")
        config.set_config_option('rax-autoscaler', 'admin_server',
                                 admin_server)

    # Re-parse the file on-disk and validate
    config.parse_config()
    config.validate()