Skip to content

Commit

Permalink
Zone file import - support missing params.
Browse files Browse the repository at this point in the history
Add support for missing parameters when importing zone files:
- networks
- views
- name

Support for the "name" field also added to create without zonefile.
  • Loading branch information
hhellyer committed Jun 21, 2024
1 parent 65954a7 commit f34ae29
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 8 deletions.
7 changes: 4 additions & 3 deletions ns1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ def searchZone(
return rest_zone.search(query, type, expand, max, callback, errback)

def createZone(
self, zone, zoneFile=None, callback=None, errback=None, **kwargs
self, zone, name=None, zoneFile=None, callback=None, errback=None, **kwargs
):
"""
Create a new zone, and return an associated high level Zone object.
Expand All @@ -371,7 +371,8 @@ def createZone(
If zoneFile is specified, upload the specific zone definition file
to populate the zone with.
:param str zone: zone name, like 'example.com'
:param str zone: zone FQDN, like 'example.com'
:param str zone: zone name override, name will be zone FQDN if omitted
:param str zoneFile: absolute path of a zone file
:keyword int retry: retry time
:keyword int refresh: refresh ttl
Expand All @@ -385,7 +386,7 @@ def createZone(
zone = ns1.zones.Zone(self.config, zone)

return zone.create(
zoneFile=zoneFile, callback=callback, errback=errback, **kwargs
zoneFile=zoneFile, name=name, callback=callback, errback=errback, **kwargs
)

def loadRecord(
Expand Down
28 changes: 25 additions & 3 deletions ns1/rest/zones.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class Zones(resource.BaseResource):
"link",
"primary_master",
"tags",
"views",
]
BOOL_FIELDS = ["dnssec"]

Expand All @@ -31,22 +32,43 @@ def _buildBody(self, zone, **kwargs):
return body

def import_file(
self, zone, zoneFile, callback=None, errback=None, **kwargs
self, zone, zoneFile, name=None, callback=None, errback=None, **kwargs
):
files = [("zonefile", (zoneFile, open(zoneFile, "rb"), "text/plain"))]
params = self._buildImportParams(kwargs, name=name)
return self._make_request(
"PUT",
"import/zonefile/%s" % (zone),
files=files,
params=params,
callback=callback,
errback=errback,
)

def create(self, zone, callback=None, errback=None, **kwargs):
# Extra import args are specified as query parameters not fields in a JSON object.
def _buildImportParams(self, fields, name=None):
params = {}
# Arrays of values should be passed as multiple instances of the same
# parameter but the zonefile API expects parameters containing comma
# seperated values.
if fields.get("networks") is not None:
networksStrs = map(str, fields["networks"])
networksParam = ",".join(networksStrs)
params["networks"] = networksParam
if fields.get("views") is not None:
viewsParam = ",".join(fields["views"])
params["views"] = viewsParam
if name is not None:
params["name"] = name
return params

def create(self, zone, name=None, callback=None, errback=None, **kwargs):
body = self._buildBody(zone, **kwargs)
if name is None:
name = zone
return self._make_request(
"PUT",
"%s/%s" % (self.ROOT, zone),
"%s/%s" % (self.ROOT, name),
body=body,
callback=callback,
errback=errback,
Expand Down
5 changes: 3 additions & 2 deletions ns1/zones.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def success(result, *args):
self.zone, callback=success, errback=errback, **kwargs
)

def create(self, zoneFile=None, callback=None, errback=None, **kwargs):
def create(self, name=None, zoneFile=None, callback=None, errback=None, **kwargs):
"""
Create a new zone. Pass a list of keywords and their values to
configure. For the list of keywords available for zone configuration,
Expand All @@ -113,13 +113,14 @@ def success(result, *args):
return self._rest.import_file(
self.zone,
zoneFile,
name=name,
callback=success,
errback=errback,
**kwargs
)
else:
return self._rest.create(
self.zone, callback=success, errback=errback, **kwargs
self.zone, name=name, callback=success, errback=errback, **kwargs
)

def __getattr__(self, item):
Expand Down
40 changes: 40 additions & 0 deletions tests/unit/test_zone.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,46 @@ def test_rest_zone_version_list(zones_config, zone, url):
)


@pytest.mark.parametrize(
"zone, name, url", [("test.zone", None, "zones/test.zone"),
("test.zone", "test.name", "zones/test.name")]
)
def test_rest_zone_create(zones_config, zone, name, url):
z = ns1.rest.zones.Zones(zones_config)
z._make_request = mock.MagicMock()
z.create(zone, name=name)
z._make_request.assert_called_once_with(
"PUT", url, body={"zone":zone}, callback=None, errback=None
)

@pytest.mark.parametrize(
"zone, name, url, networks, views",[
("test.zone", None, "import/zonefile/test.zone", None, None),
("test.zone", "test.name", "import/zonefile/test.zone", None, None),
("test.zone", "test.name", "import/zonefile/test.zone", [1,2,99], None),
("test.zone", "test.name", "import/zonefile/test.zone", None, ["view1", "view2"]),
("test.zone", "test.name", "import/zonefile/test.zone", [3,4,99], ["viewA", "viewB"]),
]
)
def test_rest_zone_import_file(zones_config, zone, name, url, networks, views):
z = ns1.rest.zones.Zones(zones_config)
z._make_request = mock.MagicMock()
params = {}
networksStrs=None
if networks is not None:
networksStrs = map(str, networks)
params['networks'] = ",".join(networksStrs)
if views is not None:
params['views'] = ",".join(views)
if name is not None:
params['name'] = name

z.import_file(zone, "../examples/importzone.db", name=name, networks=networks, views=views)

z._make_request.assert_called_once_with(
"PUT", url, files=mock.ANY, params=params, callback=None, errback=None
)

@pytest.mark.parametrize(
"zone, url", [("test.zone", "zones/test.zone/versions?force=false")]
)
Expand Down

0 comments on commit f34ae29

Please sign in to comment.