Пример #1
0
    def test_removes_existing_forwarders_config_if_migrate_set(self):
        options_file = self.make_file(contents=OPTIONS_FILE_WITH_FORWARDERS)
        call_command(
            "edit_named_options",
            config_path=options_file,
            migrate_conflicting_options=True,
            stdout=self.stdout,
        )

        # Check that the file was re-written without forwarders (since
        # that's now in the included file).
        options = read_isc_file(options_file)
        self.assertThat(make_isc_string(options), Not(Contains("forwarders")))
    def test_removes_existing_dnssec_validation_config_if_migration_set(self):
        options_file = self.make_file(contents=OPTIONS_FILE_WITH_DNSSEC)
        call_command(
            "edit_named_options",
            config_path=options_file,
            migrate_conflicting_options=True,
            stdout=self.stdout,
        )

        # Check that the file was re-written without dnssec-validation (since
        # that's now in the included file).
        options = read_isc_file(options_file)
        self.assertThat(make_isc_string(options),
                        Not(Contains("dnssec-validation")))
Пример #3
0
 def test_set_up_options_conf_write_config_assumes_no_overrides(self):
     dns_conf_dir = patch_dns_config_path(self)
     set_up_options_conf()
     target_file = os.path.join(dns_conf_dir,
                                MAAS_NAMED_CONF_OPTIONS_INSIDE_NAME)
     target = read_isc_file(target_file)
     self.assertThat(
         [
             target["allow-query"]["any"],
             target["allow-recursion"]["trusted"],
             target["allow-query-cache"]["trusted"],
         ],
         AllMatch(Equals(True)),
     )
Пример #4
0
 def test_set_up_options_conf_write_config_allows_zero_overrides(self):
     dns_conf_dir = patch_dns_config_path(self)
     factory.make_file(location=dns_conf_dir,
                       name=NAMED_CONF_OPTIONS,
                       contents=NAMED_CONF_OPTIONS_NO_ALLOW_CONTENTS)
     set_up_options_conf()
     target_file = os.path.join(dns_conf_dir,
                                MAAS_NAMED_CONF_OPTIONS_INSIDE_NAME)
     target = read_isc_file(target_file)
     self.assertThat([
         target['allow-query']['any'],
         target['allow-recursion']['trusted'],
         target['allow-query-cache']['trusted'],
     ], AllMatch(Equals(True)))
Пример #5
0
 def test_set_up_options_conf_write_config_allows_overrides(self):
     dns_conf_dir = patch_dns_config_path(self)
     factory.make_file(location=dns_conf_dir,
                       name=NAMED_CONF_OPTIONS,
                       contents=NAMED_CONF_OPTIONS_CONTENTS)
     set_up_options_conf()
     target_file = os.path.join(dns_conf_dir,
                                MAAS_NAMED_CONF_OPTIONS_INSIDE_NAME)
     target = read_isc_file(target_file)
     self.assertThat([
         target.get('allow-query'),
         target.get('allow-recursion'),
         target.get('allow-query-cache'),
     ], AllMatch(Is(None)))
Пример #6
0
def set_up_options_conf(overwrite=True, **kwargs):
    """Write out the named.conf.options.inside.maas file.

    This file should be included by the top-level named.conf.options
    inside its 'options' block.  MAAS cannot write the options file itself,
    so relies on either the DNSFixture in the test suite, or the packaging.
    Both should set that file up appropriately to include our file.
    """
    template_path = get_dns_template_path(
        "named.conf.options.inside.maas.template")
    template = tempita.Template.from_filename(template_path, encoding="UTF-8")

    # Make sure "upstream_dns" is set at least to None. It's a special piece
    # of config and we don't want to require that every call site has to
    # specify it. If it's not set, the substitution will fail with the default
    # template that uses this value.
    kwargs.setdefault("upstream_dns")
    kwargs.setdefault("dnssec_validation", "auto")

    # Parse the options file and make sure MAAS doesn't define any options
    # that the user has already customized.
    allow_user_override_options = [
        "allow-query",
        "allow-recursion",
        "allow-query-cache",
    ]

    try:
        parsed_options = read_isc_file(
            compose_bind_config_path(NAMED_CONF_OPTIONS))
    except IOError:
        parsed_options = {}

    options = parsed_options.get('options', {})
    for option in allow_user_override_options:
        kwargs['upstream_' + option.replace('-', '_')] = option in options

    try:
        rendered = template.substitute(kwargs)
    except NameError as error:
        raise DNSConfigFail(*error.args)
    else:
        # The rendered configuration is Unicode text but should contain only
        # ASCII characters. Non-ASCII records should have been treated using
        # the rules for IDNA (Internationalized Domain Names in Applications).
        rendered = rendered.encode("ascii")

    target_path = compose_config_path(MAAS_NAMED_CONF_OPTIONS_INSIDE_NAME)
    atomic_write(rendered, target_path, overwrite=overwrite, mode=0o644)
Пример #7
0
 def test_write_config_with_forwarded_zones(self):
     name = factory.make_name("domain")
     ip = factory.make_ip_address()
     forwarded_zones = [(name, [ip])]
     target_dir = patch_dns_config_path(self)
     DNSConfig(forwarded_zones=forwarded_zones).write_config()
     config_path = os.path.join(target_dir, MAAS_NAMED_CONF_NAME)
     expected_content = dedent(f"""
     zone "{name}" {{
         type forward;
         forward only;
         forwarders {{
             {ip};
         }};
     }};
     """)
     config = read_isc_file(config_path)
     expected = parse_isc_string(expected_content)
     self.assertEqual(expected[f'zone "{name}"'], config[f'zone "{name}"'])
Пример #8
0
    def test_normal_operation(self):
        options_file = self.make_file(contents=OPTIONS_FILE)
        self.run_command('--config-path', options_file)
        expected_path = os.path.join(os.path.dirname(options_file), "maas",
                                     MAAS_NAMED_CONF_OPTIONS_INSIDE_NAME)

        # Check that the file was re-written with the include statement.
        options = read_isc_file(options_file)
        self.assertThat(make_isc_string(options),
                        Contains('include "%s";' % expected_path))

        # Check that the backup was made.
        options_file_base = os.path.dirname(options_file)
        files = os.listdir(options_file_base)
        self.assertEqual(2, len(files))
        files.remove(os.path.basename(options_file))
        [backup_file] = files
        backup_file = os.path.join(options_file_base, backup_file)
        self.assertThat(backup_file, FileContains(OPTIONS_FILE))
Пример #9
0
    def test_read_isc_file(self):
        testdata = dedent("""\
            acl canonical-int-ns { 91.189.90.151; 91.189.89.192;  };

            options {
                directory "/var/cache/bind";

                forwarders {
                    91.189.94.2;
                    91.189.94.2;
                };

                dnssec-validation auto;

                auth-nxdomain no;    # conform to RFC1035
                listen-on-v6 { any; };

                allow-query { any; };
                allow-transfer { 10.222.64.1; canonical-int-ns; };

                notify explicit;
                also-notify { 91.189.90.151; 91.189.89.192;  };

                allow-query-cache { 10.222.64.0/18; };
                recursion yes;
            };

            zone "."  { type master; file "/etc/bind/db.special"; };
            """)
        testfile = self.make_file(contents=testdata)
        parsed = read_isc_file(testfile)
        self.assertEqual(
            {
                "acl canonical-int-ns": {
                    "91.189.89.192": True,
                    "91.189.90.151": True,
                },
                "options": {
                    "allow-query": {
                        "any": True
                    },
                    "allow-query-cache": {
                        "10.222.64.0/18": True
                    },
                    "allow-transfer": {
                        "10.222.64.1": True,
                        "canonical-int-ns": True,
                    },
                    "also-notify": {
                        "91.189.89.192": True,
                        "91.189.90.151": True,
                    },
                    "auth-nxdomain": "no",
                    "directory": '"/var/cache/bind"',
                    "dnssec-validation": "auto",
                    "forwarders": {
                        "91.189.94.2": True
                    },
                    "listen-on-v6": {
                        "any": True
                    },
                    "notify": "explicit",
                    "recursion": "yes",
                },
                'zone "."': {
                    "file": '"/etc/bind/db.special"',
                    "type": "master",
                },
            },
            parsed,
        )
Пример #10
0
    def test_read_isc_file(self):
        testdata = dedent("""\
            acl canonical-int-ns { 91.189.90.151; 91.189.89.192;  };

            options {
                directory "/var/cache/bind";

                forwarders {
                    91.189.94.2;
                    91.189.94.2;
                };

                dnssec-validation auto;

                auth-nxdomain no;    # conform to RFC1035
                listen-on-v6 { any; };

                allow-query { any; };
                allow-transfer { 10.222.64.1; canonical-int-ns; };

                notify explicit;
                also-notify { 91.189.90.151; 91.189.89.192;  };

                allow-query-cache { 10.222.64.0/18; };
                recursion yes;
            };

            zone "."  { type master; file "/etc/bind/db.special"; };
            """)
        testfile = self.make_file(contents=testdata)
        parsed = read_isc_file(testfile)
        self.assertEqual(
            {
                'acl canonical-int-ns': {
                    '91.189.89.192': True,
                    '91.189.90.151': True,
                },
                'options': {
                    'allow-query': {
                        'any': True
                    },
                    'allow-query-cache': {
                        '10.222.64.0/18': True
                    },
                    'allow-transfer': {
                        '10.222.64.1': True,
                        'canonical-int-ns': True,
                    },
                    'also-notify': {
                        '91.189.89.192': True,
                        '91.189.90.151': True,
                    },
                    'auth-nxdomain': 'no',
                    'directory': '"/var/cache/bind"',
                    'dnssec-validation': 'auto',
                    'forwarders': {
                        '91.189.94.2': True
                    },
                    'listen-on-v6': {
                        'any': True
                    },
                    'notify': 'explicit',
                    'recursion': 'yes'
                },
                'zone "."': {
                    'file': '"/etc/bind/db.special"',
                    'type': 'master',
                }
            }, parsed)