示例#1
0
    def test_env_var_in_include_2_levels_dont_set(self):
        settings.CONFIG_FILE = 'tests/fixtures/config_with_include_and_env_vars.yaml'
        settings.GET_ENVIRON_STRICT = True
        with self.assertRaises(RuntimeError):
            config.load_context_section('section-1')

        settings.GET_ENVIRON_STRICT = False
示例#2
0
 def test_config_is_empty(self):
     settings.CONFIG_FILE = 'tests/fixtures/empty_config.yaml'
     with self.assertRaises(RuntimeError) as context:
         config.load_context_section('section')
     self.assertTrue(
         'Config file "tests/fixtures/empty_config.yaml" is empty' in str(
             context.exception))
示例#3
0
 def test_check_empty_var(self):
     settings.CONFIG_FILE = 'tests/fixtures/config.yaml'
     settings.GET_ENVIRON_STRICT = True
     with self.assertRaises(RuntimeError) as context:
         config.load_context_section('deployment')
     settings.GET_ENVIRON_STRICT = False
     self.assertTrue('Environment variable "EMPTY_ENV" is not set' in str(
         context.exception))
示例#4
0
 def test_dashes_in_var_names(self):
     settings.TEMPLATES_DIR = 'templates_tests'
     settings.CONFIG_FILE = 'tests/fixtures/dashes_config.yaml'
     with self.assertRaises(RuntimeError) as context:
         config.load_context_section('section')
     self.assertTrue(
         'Variable names should never include dashes, '
         'check your vars, please: my-nested-var, my-var, your-var'
         in str(context.exception), context.exception)
示例#5
0
    def test_env_var_in_section2_dont_set(self):
        settings.CONFIG_FILE = 'tests/fixtures/config_with_env_vars.yaml'
        settings.GET_ENVIRON_STRICT = True
        with self.assertRaises(RuntimeError) as context:
            config.load_context_section('section-2')

        settings.GET_ENVIRON_STRICT = False
        self.assertTrue('Environment variable "SECTION2" is not set' in str(
            context.exception))
示例#6
0
 def test_generate_templates(self):
     r = templating.Renderer(
         os.path.join(os.path.dirname(__file__), 'templates_tests'))
     context = config.load_context_section('test_dirs')
     r.generate_by_context(context)
     file_path_1 = '{}/template1.yaml'.format(settings.TEMP_DIR)
     file_path_2 = '{}/template2.yaml'.format(settings.TEMP_DIR)
     file_path_3 = '{}/template3.yaml'.format(settings.TEMP_DIR)
     file_path_4 = '{}/innerdir/template1.yaml'.format(settings.TEMP_DIR)
     file_path_5 = '{}/template_include_file.yaml'.format(settings.TEMP_DIR)
     self.assertTrue(os.path.exists(file_path_1))
     self.assertTrue(os.path.exists(file_path_2))
     self.assertTrue(os.path.exists(file_path_3))
     with open(file_path_1, 'r') as f:
         content = f.read()
     self.assertEqual(content, "{'ha_ha': 'included_var'}")
     with open(file_path_2, 'r') as f:
         content = f.read()
     self.assertEqual(content, 'TXkgdmFsdWU=')
     with open(file_path_3, 'r') as f:
         content = f.read()
     self.assertEqual(content, 'My value')
     with open(file_path_4, 'r') as f:
         content = f.read()
     self.assertEqual(content, "{'ha_ha': 'included_var'}")
     with open(file_path_5, 'r') as f:
         content = f.read()
     self.assertEqual(
         content,
         "test: |\n  {{ hello world }}\n  new\n  line\n  {{ hello world1 }}\n"
     )
示例#7
0
 def test_merge_section_options(self):
     settings.TEMPLATES_DIR = 'templates_tests'
     c = config.load_context_section('test_dirs')
     self.assertEqual(c['my_var'], 'my_value')
     self.assertEqual(c['my_env_var'], 'My value')
     self.assertEqual(c['my_file'], {'ha_ha': 'included_var'})
     self.assertTrue(c['dirs'])
示例#8
0
 def test_no_templates_in_kubectl(self):
     r = templating.Renderer(
         os.path.join(os.path.dirname(__file__), 'templates_tests'))
     with self.assertRaises(RuntimeError) as context:
         r.generate_by_context(config.load_context_section('no_templates'))
     self.assertTrue('Templates section doesn\'t have any template items' in
                     str(context.exception))
示例#9
0
 def test_io_2709(self):
     r = templating.Renderer(
         os.path.join(os.path.dirname(__file__), 'templates_tests'))
     with self.assertRaises(TemplateRenderingError) as context:
         c = config.load_context_section('io_2709')
         r.generate_by_context(c)
     self.assertTrue('due to: \'undefined_variable\' is undefined' in str(
         context.exception))
示例#10
0
 def test_recursive_vars(self):
     settings.TEMPLATES_DIR = 'templates_tests'
     c = config.load_context_section('test_recursive_vars')
     self.assertEqual({'router': {
         'my': 'var',
         'my1': 'var1',
         'your': 2
     }}, c['var'])
示例#11
0
 def test_render_not_existent_template(self):
     r = templating.Renderer(
         os.path.join(os.path.dirname(__file__), 'templates_tests'))
     with self.assertRaises(TemplateRenderingError) as context:
         r.generate_by_context(
             config.load_context_section('not_existent_template'))
     self.assertTrue('doesnotexist.yaml.j2' in str(context.exception),
                     context.exception)
示例#12
0
 def test_check_k8s_settings(self):
     settings.CONFIG_FILE = 'tests/fixtures/config_without_k8s.yaml'
     c = config.load_context_section('deployment')
     with self.assertRaises(RuntimeError) as context:
         config.check_required_vars(c, [
             'k8s_master_uri', 'k8s_token', 'k8s_ca_base64', 'k8s_namespace'
         ])
     self.assertTrue(
         'Variables "k8s_token, k8s_ca_base64" not found '
         '(or empty)' in str(context.exception), )
示例#13
0
 def test_concatination_with_env(self):
     settings.TEMPLATES_DIR = 'templates_tests'
     c = config.load_context_section('test_dirs')
     self.assertEqual(c['my_conc_env_var1'], 'prefix-My value-postfix')
     self.assertEqual(c['my_conc_env_var2'], 'prefix-My value')
     self.assertEqual(c['my_conc_env_var3'], 'My value-postfix')
示例#14
0
def main():
    # INFO furiousassault: backward compatibility rough attempt
    # must be removed later according to https://github.com/2gis/k8s-handle/issues/40
    deprecation_warnings = 0
    filtered_arguments = []

    for argument in sys.argv[1:]:
        if argument in [
                '--sync-mode=true', '--sync-mode=True', '--dry-run=true',
                '--dry-run=True'
        ]:
            deprecation_warnings += 1
            filtered_arguments.append(argument.split('=')[0])
            continue

        if argument in [
                '--sync-mode=false', '--sync-mode=False', '--dry-run=false',
                '--dry-run=False'
        ]:
            deprecation_warnings += 1
            continue

        filtered_arguments.append(argument)

    args, unrecognized_args = parser.parse_known_args(filtered_arguments)

    if deprecation_warnings or unrecognized_args:
        log.warning(
            "Explicit true/false arguments to --sync-mode and --dry-run keys are deprecated "
            "and will be discontinued in the future. Use these keys without arguments instead."
        )

    args = vars(args)
    kubeconfig_namespace = None
    settings.CHECK_STATUS_TRIES = args.get('tries')
    settings.CHECK_DAEMONSET_STATUS_TRIES = args.get('tries')
    settings.CHECK_STATUS_TIMEOUT = args.get('retry_delay')
    settings.CHECK_DAEMONSET_STATUS_TIMEOUT = args.get('retry_delay')
    settings.GET_ENVIRON_STRICT = args.get('strict')
    settings.COUNT_LOG_LINES = args.get('tail_lines')
    settings.CONFIG_FILE = args.get('config') or settings.CONFIG_FILE

    try:
        context = config.load_context_section(args['section'])
        render = templating.Renderer(settings.TEMPLATES_DIR)
        resources = render.generate_by_context(context)
        evaluator = config.PriorityEvaluator(args, context, os.environ)

        if evaluator.environment_deprecated():
            log.warning(
                "K8S_HOST and K8S_CA environment variables support is deprecated "
                "and will be discontinued in the future. Use K8S_MASTER_URI and K8S_CA_BASE64 instead."
            )

        if args.get('dry_run'):
            return

        # INFO rvadim: https://github.com/kubernetes-client/python/issues/430#issuecomment-359483997
        if args.get('use_kubeconfig'):
            try:
                load_kube_config()
                kubeconfig_namespace = list_kube_config_contexts()[1].get(
                    'context').get('namespace')
            except Exception as e:
                raise RuntimeError(e)
        else:
            client.Configuration.set_default(
                evaluator.k8s_client_configuration())

        settings.K8S_NAMESPACE = evaluator.k8s_namespace_default(
            kubeconfig_namespace)
        log.info('Default namespace "{}"'.format(settings.K8S_NAMESPACE))

        if not settings.K8S_NAMESPACE:
            log.info(
                "Default namespace is not set. "
                "This may lead to provisioning error, if namespace is not set for each resource."
            )

        p = Provisioner(args['command'], args.get('sync_mode'),
                        args.get('show_logs'))
        d = ApiDeprecationChecker(
            client.VersionApi().get_code().git_version[1:])

        for resource in resources:
            d.run(resource)

        for resource in resources:
            p.run(resource)

    except templating.TemplateRenderingError as e:
        log.error('Template generation error: {}'.format(e))
        sys.exit(1)
    except InvalidYamlError as e:
        log.error('{}'.format(e))
        sys.exit(1)
    except DeprecationError as e:
        log.error('Deprecation warning: {}'.format(e))
        sys.exit(1)
    except RuntimeError as e:
        log.error('RuntimeError: {}'.format(e))
        sys.exit(1)
    except ProvisioningError:
        sys.exit(1)

    print(r'''
                         _(_)_                          wWWWw   _
             @@@@       (_)@(_)   vVVVv     _     @@@@  (___) _(_)_
            @@()@@ wWWWw  (_)\    (___)   _(_)_  @@()@@   Y  (_)@(_)
             @@@@  (___)     `|/    Y    (_)@(_)  @@@@   \|/   (_)
              /      Y       \|    \|/    /(_)    \|      |/      |
           \ |     \ |/       | / \ | /  \|/       |/    \|      \|/
            \|//    \|///    \|//  \|/// \|///    \|//    |//    \|//
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^''')
示例#15
0
 def test_common_section(self):
     with self.assertRaises(RuntimeError) as context:
         config.load_context_section(settings.COMMON_SECTION_NAME)
     self.assertTrue('Section "{}" is not intended to deploy'.format(
         settings.COMMON_SECTION_NAME) in str(context.exception))
示例#16
0
 def test_no_templates(self):
     with self.assertRaises(RuntimeError) as context:
         config.load_context_section('no_templates_section')
     self.assertTrue(
         'Section "templates" or "kubectl" not found in config file' in str(
             context.exception))
示例#17
0
 def test_not_existed_section(self):
     with self.assertRaises(RuntimeError) as context:
         config.load_context_section('absent_section')
     self.assertTrue(
         'Section "absent_section" not found' in str(context.exception))
示例#18
0
 def test_config_incorrect(self):
     settings.CONFIG_FILE = 'tests/fixtures/incorrect_config.yaml'
     with self.assertRaises(InvalidYamlError):
         config.load_context_section('section')
示例#19
0
 def test_config_not_exist(self):
     settings.CONFIG_FILE = 'tests/config.yaml'
     with self.assertRaises(Exception) as context:
         config.load_context_section('section')
     self.assertTrue('No such file or directory: \'tests/config.yaml\'' in
                     str(context.exception))
示例#20
0
def main():
    # INFO furiousassault: backward compatibility rough attempt
    # must be removed later according to https://github.com/2gis/k8s-handle/issues/40
    deprecation_warnings = 0
    filtered_arguments = []

    for argument in sys.argv[1:]:
        if argument in ['--sync-mode=true', '--sync-mode=True', '--dry-run=true', '--dry-run=True']:
            deprecation_warnings += 1
            filtered_arguments.append(argument.split('=')[0])
            continue

        if argument in ['--sync-mode=false', '--sync-mode=False', '--dry-run=false', '--dry-run=False']:
            deprecation_warnings += 1
            continue

        filtered_arguments.append(argument)

    args, unrecognized_args = parser.parse_known_args(filtered_arguments)

    if deprecation_warnings or unrecognized_args:
        log.warning("Explicit true/false arguments to --sync-mode and --dry-run keys are deprecated "
                    "and will be removed in the future. Use these keys without arguments instead.")

    if 'config' in args and args.config:
        settings.CONFIG_FILE = args.config

    if 'tries' in args:
        settings.CHECK_STATUS_TRIES = args.tries
        settings.CHECK_DAEMONSET_STATUS_TRIES = args.tries

    if 'retry_delay' in args:
        settings.CHECK_STATUS_TIMEOUT = args.retry_delay
        settings.CHECK_DAEMONSET_STATUS_TIMEOUT = args.retry_delay

    if 'strict' in args:
        settings.GET_ENVIRON_STRICT = args.strict

    if 'tail_lines' in args:
        settings.COUNT_LOG_LINES = args.tail_lines

    show_logs = False

    if 'show_logs' in args:
        show_logs = args.show_logs

    try:
        context = config.load_context_section(args.section)
        render = templating.Renderer(settings.TEMPLATES_DIR)
        resources = render.generate_by_context(context)
        # INFO rvadim: https://github.com/kubernetes-client/python/issues/430#issuecomment-359483997

        if args.dry_run:
            return

        if 'use_kubeconfig' in args and args.use_kubeconfig:
            load_kube_config()
            namespace = list_kube_config_contexts()[1].get('context').get('namespace')

            if not namespace:
                raise RuntimeError("Unable to determine namespace of current context")

            settings.K8S_NAMESPACE = namespace
        else:
            Configuration.set_default(get_client_config(context))
            check_required_vars(context, ['k8s_master_uri', 'k8s_token', 'k8s_ca_base64', 'k8s_namespace'])

        if context.get('k8s_namespace'):
            settings.K8S_NAMESPACE = context.get('k8s_namespace')

        log.info('Default namespace "{}"'.format(settings.K8S_NAMESPACE))
        p = Provisioner(args.command, args.sync_mode, show_logs)
        d = ApiDeprecationChecker(VersionApi().get_code().git_version[1:])

        for resource in resources:
            d.run(resource)

        for resource in resources:
            p.run(resource)

    except templating.TemplateRenderingError as e:
        log.error('Template generation error: {}'.format(e))
        sys.exit(1)
    except InvalidYamlError as e:
        log.error('{}'.format(e))
        sys.exit(1)
    except DeprecationError as e:
        log.error('Deprecation warning: {}'.format(e))
        sys.exit(1)
    except RuntimeError as e:
        log.error('RuntimeError: {}'.format(e))
        sys.exit(1)
    except ProvisioningError:
        sys.exit(1)

    print('''
                         _(_)_                          wWWWw   _
             @@@@       (_)@(_)   vVVVv     _     @@@@  (___) _(_)_
            @@()@@ wWWWw  (_)\    (___)   _(_)_  @@()@@   Y  (_)@(_)
             @@@@  (___)     `|/    Y    (_)@(_)  @@@@   \|/   (_)
              /      Y       \|    \|/    /(_)    \|      |/      |
           \ |     \ |/       | / \ | /  \|/       |/    \|      \|/
            \|//    \|///    \|//  \|/// \|///    \|//    |//    \|//
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^''')
示例#21
0
 def test_infinite_recursion_loop(self):
     settings.CONFIG_FILE = 'tests/fixtures/config_with_include_and_env_vars.yaml'
     with self.assertRaises(RuntimeError):
         config.load_context_section('section-3')