Exemplo n.º 1
0
    def test_issue_7754(self):
        old_cwd = os.getcwd()
        config_dir = os.path.join(integration.TMP, 'issue-7754')
        if not os.path.isdir(config_dir):
            os.makedirs(config_dir)

        os.chdir(config_dir)

        config_file_name = 'master'
        pid_path = os.path.join(config_dir, '{0}.pid'.format(config_file_name))

        shutil.copyfile(
            self.get_config_file_path('minion'),
            os.path.join(config_dir, 'minion')
        )
        config = salt.config.syndic_config(
            master_config_path=self.get_config_file_path('syndic'),
            minion_config_path=self.get_config_file_path('minion')
        )
        config.pop('include')
        config['root_dir'] = config_dir
        config['log_file'] = 'file:///dev/log/LOG_LOCAL3'
        config['ret_port'] = int(config['ret_port']) + 10
        config['publish_port'] = int(config['publish_port']) + 10

        open(os.path.join(config_dir, config_file_name), 'w').write(
            yaml.dump(config, default_flow_style=False)
        )

        self.run_script(
            self._call_binary_,
            '--config-dir {0} --pid-file {1} -l debug'.format(
                config_dir,
                pid_path
            ),
            timeout=5,
            catch_stderr=True
        )

        # Now kill it if still running
        if os.path.exists(pid_path):
            try:
                os.kill(int(open(pid_path).read()), signal.SIGKILL)
            except OSError:
                pass
        try:
            self.assertFalse(os.path.isdir(os.path.join(config_dir, 'file:')))
        finally:
            os.chdir(old_cwd)
            if os.path.isdir(config_dir):
                shutil.rmtree(config_dir)
Exemplo n.º 2
0
    def test_issue_7754(self):
        old_cwd = os.getcwd()
        config_dir = os.path.join(integration.TMP, 'issue-7754')
        if not os.path.isdir(config_dir):
            os.makedirs(config_dir)

        os.chdir(config_dir)

        config_file_name = 'master'
        pid_path = os.path.join(config_dir, '{0}.pid'.format(config_file_name))

        shutil.copyfile(self.get_config_file_path('minion'),
                        os.path.join(config_dir, 'minion'))
        config = salt.config.syndic_config(
            master_config_path=self.get_config_file_path('syndic'),
            minion_config_path=self.get_config_file_path('minion'))
        config.pop('include')
        config['root_dir'] = config_dir
        config['log_file'] = 'file:///dev/log/LOG_LOCAL3'
        config['ret_port'] = int(config['ret_port']) + 10
        config['publish_port'] = int(config['publish_port']) + 10

        open(os.path.join(config_dir, config_file_name),
             'w').write(yaml.dump(config, default_flow_style=False))

        self.run_script(self._call_binary_,
                        '--config-dir {0} --pid-file {1} -l debug'.format(
                            config_dir, pid_path),
                        timeout=5,
                        catch_stderr=True)

        # Now kill it if still running
        if os.path.exists(pid_path):
            try:
                os.kill(int(open(pid_path).read()), signal.SIGKILL)
            except OSError:
                pass
        try:
            self.assertFalse(os.path.isdir(os.path.join(config_dir, 'file:')))
        finally:
            os.chdir(old_cwd)
            if os.path.isdir(config_dir):
                shutil.rmtree(config_dir)
Exemplo n.º 3
0
    def write_config(cls, config):
        cls.verify_config(config)
        config_file = config.pop("conf_file")
        log.debug(
            "Writing to configuration file %s. Configuration:\n%s",
            config_file,
            pprint.pformat(config),
        )

        # Write down the computed configuration into the config file
        with salt.utils.files.fopen(config_file, "w") as wfh:
            salt.utils.yaml.safe_dump(config, wfh, default_flow_style=False)
        return salt.config.cloud_config(config_file)
Exemplo n.º 4
0
def apply_cloud_providers_config(overrides, defaults=None):
    '''
    Apply the loaded cloud providers configuration.
    '''
    if defaults is None:
        defaults = PROVIDER_CONFIG_DEFAULTS

    config = defaults.copy()
    if overrides:
        config.update(overrides)

    # Is the user still using the old format in the new configuration file?!
    for name, settings in config.copy().items():
        if '.' in name:
            log.warn(
                'Please switch to the new providers configuration syntax'
            )

            # Let's help out and migrate the data
            config = old_to_new(config)

            # old_to_new will migrate the old data into the 'providers' key of
            # the config dictionary. Let's map it correctly
            for prov_name, prov_settings in config.pop('providers').items():
                config[prov_name] = prov_settings
            break

    providers = {}
    for key, val in config.items():
        if key in ('conf_file', 'include', 'default_include'):
            continue

        if not isinstance(val, (list, tuple)):
            val = [val]
        else:
            # Need to check for duplicate cloud provider entries per "alias" or
            # we won't be able to properly reference it.
            handled_providers = set()
            for details in val:
                if 'provider' not in details:
                    if 'extends' not in details:
                        log.error(
                            'Please check your cloud providers configuration. '
                            'There\'s no \'provider\' nor \'extends\' '
                            'definition. So it\'s pretty useless.'
                        )
                    continue
                if details['provider'] in handled_providers:
                    log.error(
                        'You can only have one entry per cloud provider. For '
                        'example, if you have a cloud provider configuration '
                        'section named, \'production\', you can only have a '
                        'single entry for EC2, Joyent, Openstack, and so '
                        'forth.'
                    )
                    raise salt.cloud.exceptions.SaltCloudConfigError(
                        'The cloud provider alias {0!r} has multiple entries '
                        'for the {1[provider]!r} driver.'.format(key, details)
                    )
                handled_providers.add(details['provider'])

        for entry in val:
            if 'provider' not in entry:
                entry['provider'] = '-only-extendable-'

            if key not in providers:
                providers[key] = {}

            provider = entry['provider']
            if provider in providers[key] and provider == '-only-extendable-':
                raise salt.cloud.exceptions.SaltCloudConfigError(
                    'There\'s multiple entries under {0!r} which do not set '
                    'a provider setting. This is most likely just a holder '
                    'for data to be extended from, however, there can be '
                    'only one entry which does not define it\'s \'provider\' '
                    'setting.'.format(key)
                )
            elif provider not in providers[key]:
                providers[key][provider] = entry

    # Is any provider extending data!?
    while True:
        keep_looping = False
        for provider_alias, entries in providers.copy().items():

            for driver, details in entries.iteritems():
                # Set a holder for the defined profiles
                providers[provider_alias][driver]['profiles'] = {}

                if 'extends' not in details:
                    continue

                extends = details.pop('extends')

                if ':' in extends:
                    alias, provider = extends.split(':')
                    if alias not in providers:
                        raise salt.cloud.exceptions.SaltCloudConfigError(
                            'The {0!r} cloud provider entry in {1!r} is '
                            'trying to extend data from {2!r} though {2!r} '
                            'is not defined in the salt cloud providers '
                            'loaded data.'.format(
                                details['provider'],
                                provider_alias,
                                alias
                            )
                        )

                    if provider not in providers.get(alias):
                        raise salt.cloud.exceptions.SaltCloudConfigError(
                            'The {0!r} cloud provider entry in {1!r} is '
                            'trying to extend data from \'{2}:{3}\' though '
                            '{3!r} is not defined in {1!r}'.format(
                                details['provider'],
                                provider_alias,
                                alias,
                                provider
                            )
                        )
                    details['extends'] = '{0}:{1}'.format(alias, provider)
                elif providers.get(extends) and len(providers[extends]) > 1:
                    raise salt.cloud.exceptions.SaltCloudConfigError(
                        'The {0!r} cloud provider entry in {1!r} is trying '
                        'to extend from {2!r} which has multiple entries '
                        'and no provider is being specified. Not '
                        'extending!'.format(
                            details['provider'], provider_alias, extends
                        )
                    )
                elif extends not in providers:
                    raise salt.cloud.exceptions.SaltCloudConfigError(
                        'The {0!r} cloud provider entry in {1!r} is trying '
                        'to extend data from {2!r} though {2!r} is not '
                        'defined in the salt cloud providers loaded '
                        'data.'.format(
                            details['provider'], provider_alias, extends
                        )
                    )
                else:
                    provider = providers.get(extends)
                    if driver in providers.get(extends):
                        details['extends'] = '{0}:{1}'.format(extends, driver)
                    elif '-only-extendable-' in providers.get(extends):
                        details['extends'] = '{0}:{1}'.format(
                            extends, '-only-extendable-'
                        )
                    else:
                        # We're still not aware of what we're trying to extend
                        # from. Let's try on next iteration
                        details['extends'] = extends
                        keep_looping = True
        if not keep_looping:
            break

    while True:
        # Merge provided extends
        keep_looping = False
        for alias, entries in providers.copy().items():
            for driver, details in entries.iteritems():

                if 'extends' not in details:
                    # Extends resolved or non existing, continue!
                    continue

                if 'extends' in details['extends']:
                    # Since there's a nested extends, resolve this one in the
                    # next iteration
                    keep_looping = True
                    continue

                # Let's get a reference to what we're supposed to extend
                extends = details.pop('extends')
                # Split the setting in (alias, driver)
                ext_alias, ext_driver = extends.split(':')
                # Grab a copy of what should be extended
                extended = providers.get(ext_alias).get(ext_driver).copy()
                # Merge the data to extend with the details
                extended.update(details)
                # Update the providers dictionary with the merged data
                providers[alias][driver] = extended

        if not keep_looping:
            break

    # Now clean up any providers entry that was just used to be a data tree to
    # extend from
    for provider_alias, entries in providers.copy().items():
        for driver, details in entries.copy().iteritems():
            if driver != '-only-extendable-':
                continue

            log.info(
                'There\'s at least one cloud driver details under the {0!r} '
                'cloud provider alias which does not have the required '
                '\'provider\' setting. Was probably just used as a holder '
                'for additional data. Removing it from the available '
                'providers listing'.format(
                    provider_alias
                )
            )
            providers[provider_alias].pop(driver)

        if not providers[provider_alias]:
            providers.pop(provider_alias)

    return providers
Exemplo n.º 5
0
def apply_cloud_providers_config(overrides, defaults=None):
    '''
    Apply the loaded cloud providers configuration.
    '''
    if defaults is None:
        defaults = PROVIDER_CONFIG_DEFAULTS

    config = defaults.copy()
    if overrides:
        config.update(overrides)

    # Is the user still using the old format in the new configuration file?!
    for name, settings in config.copy().items():
        if '.' in name:
            log.warn('Please switch to the new providers configuration syntax')

            # Let's help out and migrate the data
            config = old_to_new(config)

            # old_to_new will migrate the old data into the 'providers' key of
            # the config dictionary. Let's map it correctly
            for prov_name, prov_settings in config.pop('providers').items():
                config[prov_name] = prov_settings
            break

    providers = {}
    for key, val in config.items():
        if key in ('conf_file', 'include', 'default_include'):
            continue

        if not isinstance(val, (list, tuple)):
            val = [val]
        else:
            # Need to check for duplicate cloud provider entries per "alias" or
            # we won't be able to properly reference it.
            handled_providers = set()
            for details in val:
                if 'provider' not in details:
                    if 'extends' not in details:
                        log.error(
                            'Please check your cloud providers configuration. '
                            'There\'s no \'provider\' nor \'extends\' '
                            'definition. So it\'s pretty useless.')
                    continue
                if details['provider'] in handled_providers:
                    log.error(
                        'You can only have one entry per cloud provider. For '
                        'example, if you have a cloud provider configuration '
                        'section named, \'production\', you can only have a '
                        'single entry for EC2, Joyent, Openstack, and so '
                        'forth.')
                    raise salt.cloud.exceptions.SaltCloudConfigError(
                        'The cloud provider alias {0!r} has multiple entries '
                        'for the {1[provider]!r} driver.'.format(key, details))
                handled_providers.add(details['provider'])

        for entry in val:
            if 'provider' not in entry:
                entry['provider'] = '-only-extendable-'

            if key not in providers:
                providers[key] = {}

            provider = entry['provider']
            if provider in providers[key] and provider == '-only-extendable-':
                raise salt.cloud.exceptions.SaltCloudConfigError(
                    'There\'s multiple entries under {0!r} which do not set '
                    'a provider setting. This is most likely just a holder '
                    'for data to be extended from, however, there can be '
                    'only one entry which does not define it\'s \'provider\' '
                    'setting.'.format(key))
            elif provider not in providers[key]:
                providers[key][provider] = entry

    # Is any provider extending data!?
    while True:
        keep_looping = False
        for provider_alias, entries in providers.copy().items():

            for driver, details in entries.iteritems():
                # Set a holder for the defined profiles
                providers[provider_alias][driver]['profiles'] = {}

                if 'extends' not in details:
                    continue

                extends = details.pop('extends')

                if ':' in extends:
                    alias, provider = extends.split(':')
                    if alias not in providers:
                        raise salt.cloud.exceptions.SaltCloudConfigError(
                            'The {0!r} cloud provider entry in {1!r} is '
                            'trying to extend data from {2!r} though {2!r} '
                            'is not defined in the salt cloud providers '
                            'loaded data.'.format(details['provider'],
                                                  provider_alias, alias))

                    if provider not in providers.get(alias):
                        raise salt.cloud.exceptions.SaltCloudConfigError(
                            'The {0!r} cloud provider entry in {1!r} is '
                            'trying to extend data from \'{2}:{3}\' though '
                            '{3!r} is not defined in {1!r}'.format(
                                details['provider'], provider_alias, alias,
                                provider))
                    details['extends'] = '{0}:{1}'.format(alias, provider)
                elif providers.get(extends) and len(providers[extends]) > 1:
                    raise salt.cloud.exceptions.SaltCloudConfigError(
                        'The {0!r} cloud provider entry in {1!r} is trying '
                        'to extend from {2!r} which has multiple entries '
                        'and no provider is being specified. Not '
                        'extending!'.format(details['provider'],
                                            provider_alias, extends))
                elif extends not in providers:
                    raise salt.cloud.exceptions.SaltCloudConfigError(
                        'The {0!r} cloud provider entry in {1!r} is trying '
                        'to extend data from {2!r} though {2!r} is not '
                        'defined in the salt cloud providers loaded '
                        'data.'.format(details['provider'], provider_alias,
                                       extends))
                else:
                    provider = providers.get(extends)
                    if driver in providers.get(extends):
                        details['extends'] = '{0}:{1}'.format(extends, driver)
                    elif '-only-extendable-' in providers.get(extends):
                        details['extends'] = '{0}:{1}'.format(
                            extends, '-only-extendable-')
                    else:
                        # We're still not aware of what we're trying to extend
                        # from. Let's try on next iteration
                        details['extends'] = extends
                        keep_looping = True
        if not keep_looping:
            break

    while True:
        # Merge provided extends
        keep_looping = False
        for alias, entries in providers.copy().items():
            for driver, details in entries.iteritems():

                if 'extends' not in details:
                    # Extends resolved or non existing, continue!
                    continue

                if 'extends' in details['extends']:
                    # Since there's a nested extends, resolve this one in the
                    # next iteration
                    keep_looping = True
                    continue

                # Let's get a reference to what we're supposed to extend
                extends = details.pop('extends')
                # Split the setting in (alias, driver)
                ext_alias, ext_driver = extends.split(':')
                # Grab a copy of what should be extended
                extended = providers.get(ext_alias).get(ext_driver).copy()
                # Merge the data to extend with the details
                extended.update(details)
                # Update the providers dictionary with the merged data
                providers[alias][driver] = extended

        if not keep_looping:
            break

    # Now clean up any providers entry that was just used to be a data tree to
    # extend from
    for provider_alias, entries in providers.copy().items():
        for driver, details in entries.copy().iteritems():
            if driver != '-only-extendable-':
                continue

            log.info(
                'There\'s at least one cloud driver details under the {0!r} '
                'cloud provider alias which does not have the required '
                '\'provider\' setting. Was probably just used as a holder '
                'for additional data. Removing it from the available '
                'providers listing'.format(provider_alias))
            providers[provider_alias].pop(driver)

        if not providers[provider_alias]:
            providers.pop(provider_alias)

    return providers