print_serverinfo(self.outf, typeid, res)
+def _add_integer_options(table, takes_options, integer_properties):
+ """Generate options for cmd_zoneoptions"""
+ for k, doc, _min, _max in table:
+ o = '--' + k.lower()
+ opt = Option(o,
+ help=f"{doc} [{_min}-{_max}]",
+ type="int",
+ dest=k)
+ takes_options.append(opt)
+ integer_properties.append((k, _min, _max, o))
+
+
+class cmd_zoneoptions(Command):
+ """Change zone aging options."""
+
+ synopsis = '%prog <server> <zone> [options]'
+
+ takes_args = ['server', 'zone']
+
+ takes_optiongroups = {
+ "sambaopts": options.SambaOptions,
+ "versionopts": options.VersionOptions,
+ "credopts": options.CredentialsOptions,
+ }
+
+ takes_options = [
+ Option('--client-version', help='Client Version',
+ default='longhorn', metavar='w2k|dotnet|longhorn',
+ choices=['w2k', 'dotnet', 'longhorn'], dest='cli_ver'),
+ ]
+
+ integer_properties = []
+ # Any zone parameter that is stored as an integer (which is most of
+ # them) can be added to this table. The name should be the dnsp
+ # mixed case name, which will get munged into a lowercase name for
+ # the option. (e.g. "Aging" becomes "--aging").
+ #
+ # Note: just because we add a name here doesn't mean we will use
+ # it.
+ _add_integer_options([
+ # ( name, help-string, min, max )
+ ('Aging', 'Enable record aging', 0, 1),
+ ('NoRefreshInterval',
+ 'Aging no refresh interval in hours (0: use default)',
+ 0, 10 * 365 * 24),
+ ('RefreshInterval',
+ 'Aging refresh interval in hours (0: use default)',
+ 0, 10 * 365 * 24),
+ ],
+ takes_options,
+ integer_properties)
+
+ def run(self, server, zone, cli_ver, sambaopts=None, credopts=None,
+ versionopts=None, **kwargs):
+ self.lp = sambaopts.get_loadparm()
+ self.creds = credopts.get_credentials(self.lp)
+ dns_conn = dns_connect(server, self.lp, self.creds)
+
+ client_version = dns_client_version(cli_ver)
+ nap_type = dnsserver.DNSSRV_TYPEID_NAME_AND_PARAM
+
+ for k, _min, _max, o in self.integer_properties:
+ if kwargs.get(k) is None:
+ continue
+ v = kwargs[k]
+ if _min is not None and v < _min:
+ raise CommandError(f"{o} must be at least {_min}")
+ if _max is not None and v > _max:
+ raise CommandError(f"{o} can't exceed {_max}")
+
+ name_param = dnsserver.DNS_RPC_NAME_AND_PARAM()
+ name_param.dwParam = v
+ name_param.pszNodeName = k
+ try:
+ dns_conn.DnssrvOperation2(client_version,
+ 0,
+ server,
+ zone,
+ 0,
+ 'ResetDwordProperty',
+ nap_type,
+ name_param)
+ except WERRORError as e:
+ raise CommandError(f"Could not set {k} to {v}") from None
+
+ print(f"Set {k} to {v}", file=self.outf)
+
+
class cmd_zoneinfo(Command):
"""Query for zone information."""
subcommands = {}
subcommands['serverinfo'] = cmd_serverinfo()
+ subcommands['zoneoptions'] = cmd_zoneoptions()
subcommands['zoneinfo'] = cmd_zoneinfo()
subcommands['zonelist'] = cmd_zonelist()
subcommands['zonecreate'] = cmd_zonecreate()
import os
import ldb
+import re
from samba.auth import system_session
from samba.samdb import SamDB
err,
"Failed to print zoneinfo")
self.assertTrue(out != '')
+
+ def test_zoneoptions(self):
+ for options, vals, error in (
+ (['--aging=1'], {'fAging': 'TRUE'}, False),
+ (['--aging=0'], {'fAging': 'FALSE'}, False),
+ (['--aging=-1'], {'fAging': 'FALSE'}, True),
+ (['--aging=2'], {}, True),
+ (['--aging=2', '--norefreshinterval=1'], {}, True),
+ (['--aging=1', '--norefreshinterval=1'],
+ {'fAging': 'TRUE', 'dwNoRefreshInterval': '1'}, False),
+ (['--aging=1', '--norefreshinterval=0'],
+ {'fAging': 'TRUE', 'dwNoRefreshInterval': '0'}, False),
+ (['--aging=0', '--norefreshinterval=99', '--refreshinterval=99'],
+ {'fAging': 'FALSE',
+ 'dwNoRefreshInterval': '99',
+ 'dwRefreshInterval': '99'}, False),
+ (['--aging=0', '--norefreshinterval=-99', '--refreshinterval=99'],
+ {}, True),
+ (['--refreshinterval=9999999'], {}, True),
+ (['--norefreshinterval=9999999'], {}, True),
+ ):
+ result, out, err = self.runsubcmd("dns",
+ "zoneoptions",
+ os.environ["SERVER"],
+ self.zone,
+ self.creds_string,
+ *options)
+ if error:
+ self.assertCmdFail(result, "zoneoptions should fail")
+ else:
+ self.assertCmdSuccess(result,
+ out,
+ err,
+ "zoneoptions shouldn't fail")
+
+
+ info_r, info_out, info_err = self.runsubcmd("dns",
+ "zoneinfo",
+ os.environ["SERVER"],
+ self.zone,
+ self.creds_string)
+
+ self.assertCmdSuccess(info_r,
+ info_out,
+ info_err,
+ "zoneinfo shouldn't fail after zoneoptions")
+
+ info = {k: v for k, v in re.findall(r'^\s*(\w+)\s*:\s*(\w+)\s*$',
+ info_out,
+ re.MULTILINE)}
+ for k, v in vals.items():
+ self.assertIn(k, info)
+ self.assertEqual(v, info[k])