diff --git a/google/cloud/dns/changes.py b/google/cloud/dns/changes.py index aaf03b6..b5c8612 100644 --- a/google/cloud/dns/changes.py +++ b/google/cloud/dns/changes.py @@ -188,25 +188,45 @@ def _require_client(self, client): client = self.zone._client return client + @staticmethod + def _routing_policy_cleaner(rrs_dict): + """If ``routingPolicy`` or ``rrdatas`` are falsy, delete them. + + :type rrs_dict: dict + :param rrs_dict: dict representation of a + :class:`google.cloud.dns.resource_record_set.ResourceRecordSet`. + """ + if not rrs_dict["routingPolicy"]: + del rrs_dict["routingPolicy"] + if not rrs_dict["rrdatas"]: + del rrs_dict["rrdatas"] + return rrs_dict + def _build_resource(self): """Generate a resource for ``create``.""" additions = [ - { - "name": added.name, - "type": added.record_type, - "ttl": str(added.ttl), - "rrdatas": added.rrdatas, - } + self._routing_policy_cleaner( + { + "name": added.name, + "type": added.record_type, + "ttl": str(added.ttl), + "rrdatas": added.rrdatas, + "routingPolicy": added.routing_policy, + } + ) for added in self.additions ] deletions = [ - { - "name": deleted.name, - "type": deleted.record_type, - "ttl": str(deleted.ttl), - "rrdatas": deleted.rrdatas, - } + self._routing_policy_cleaner( + { + "name": deleted.name, + "type": deleted.record_type, + "ttl": str(deleted.ttl), + "rrdatas": deleted.rrdatas, + "routingPolicy": deleted.routing_policy, + } + ) for deleted in self.deletions ] diff --git a/google/cloud/dns/resource_record_set.py b/google/cloud/dns/resource_record_set.py index ebb9310..97a1e14 100644 --- a/google/cloud/dns/resource_record_set.py +++ b/google/cloud/dns/resource_record_set.py @@ -35,15 +35,20 @@ class ResourceRecordSet(object): :type rrdatas: list of string :param rrdatas: one or more lines containing the resource data. + :type routing_policy: dict + :param routing_policy: a dict containing the record's routing_policy. + Pass an empty dict if not needed. + :type zone: :class:`google.cloud.dns.zone.ManagedZone` :param zone: A zone which holds one or more record sets. """ - def __init__(self, name, record_type, ttl, rrdatas, zone): + def __init__(self, name, record_type, ttl, rrdatas, routing_policy, zone): self.name = name self.record_type = record_type self.ttl = ttl self.rrdatas = rrdatas + self.routing_policy = routing_policy self.zone = zone @classmethod @@ -62,5 +67,6 @@ def from_api_repr(cls, resource, zone): name = resource["name"] record_type = resource["type"] ttl = int(resource["ttl"]) - rrdatas = resource["rrdatas"] - return cls(name, record_type, ttl, rrdatas, zone=zone) + rrdatas = resource.get("rrdatas", []) + routing_policy = resource.get("routingPolicy", {}) + return cls(name, record_type, ttl, rrdatas, routing_policy, zone=zone) diff --git a/google/cloud/dns/zone.py b/google/cloud/dns/zone.py index 71ab81c..a314656 100644 --- a/google/cloud/dns/zone.py +++ b/google/cloud/dns/zone.py @@ -172,7 +172,7 @@ def name_server_set(self, value): raise ValueError("Pass a string, or None") self._properties["nameServerSet"] = value - def resource_record_set(self, name, record_type, ttl, rrdatas): + def resource_record_set(self, name, record_type, ttl, rrdatas, routing_policy): """Construct a resource record set bound to this zone. :type name: str @@ -187,10 +187,15 @@ def resource_record_set(self, name, record_type, ttl, rrdatas): :type rrdatas: list of string :param rrdatas: resource data for the RR + :type routing_policy: dict + :param routing_policy: a dict containing the record's routing_policy + :rtype: :class:`google.cloud.dns.resource_record_set.ResourceRecordSet` :returns: a new ``ResourceRecordSet`` instance """ - return ResourceRecordSet(name, record_type, ttl, rrdatas, zone=self) + return ResourceRecordSet( + name, record_type, ttl, rrdatas, routing_policy, zone=self + ) def changes(self): """Construct a change set bound to this zone. diff --git a/setup.py b/setup.py index e90db46..ea0fb81 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ name = "google-cloud-dns" description = "Google Cloud DNS API client library" -version = "0.34.1" +version = "0.35.0" # Should be one of: # 'Development Status :: 3 - Alpha' # 'Development Status :: 4 - Beta' diff --git a/tests/unit/test_changes.py b/tests/unit/test_changes.py index 6171108..eedee4a 100644 --- a/tests/unit/test_changes.py +++ b/tests/unit/test_changes.py @@ -147,7 +147,7 @@ def test_add_record_set(self): zone = _Zone() changes = self._make_one(zone) rrs = ResourceRecordSet( - "test.example.com", "CNAME", 3600, ["www.example.com"], zone + "test.example.com", "CNAME", 3600, ["www.example.com"], {}, zone ) changes.add_record_set(rrs) self.assertEqual(list(changes.additions), [rrs]) @@ -165,7 +165,7 @@ def test_delete_record_set(self): zone = _Zone() changes = self._make_one(zone) rrs = ResourceRecordSet( - "test.example.com", "CNAME", 3600, ["www.example.com"], zone + "test.example.com", "CNAME", 3600, ["www.example.com"], {}, zone ) changes.delete_record_set(rrs) self.assertEqual(list(changes.deletions), [rrs]) @@ -195,12 +195,12 @@ def test_create_w_bound_client(self): changes = self._make_one(zone) changes.add_record_set( ResourceRecordSet( - "test.example.com", "CNAME", 3600, ["www.example.com"], zone + "test.example.com", "CNAME", 3600, ["www.example.com"], {}, zone ) ) changes.delete_record_set( ResourceRecordSet( - "test.example.com", "CNAME", 86400, ["other.example.com"], zone + "test.example.com", "CNAME", 86400, ["other.example.com"], {}, zone ) ) @@ -228,12 +228,12 @@ def test_create_w_alternate_client(self): changes = self._make_one(zone) changes.add_record_set( ResourceRecordSet( - "test.example.com", "CNAME", 3600, ["www.example.com"], zone + "test.example.com", "CNAME", 3600, ["www.example.com"], {}, zone ) ) changes.delete_record_set( ResourceRecordSet( - "test.example.com", "CNAME", 86400, ["other.example.com"], zone + "test.example.com", "CNAME", 86400, ["other.example.com"], {}, zone ) ) @@ -339,6 +339,40 @@ def test_reload_w_alternate_client(self): self.assertEqual(req["path"], "/%s" % PATH) self._verifyResourceProperties(changes, RESOURCE, zone) + def test__routing_policy_cleaner_falsy(self): + conn = _Connection() + client = _Client(project=self.PROJECT, connection=conn) + zone = _Zone(client) + changes = self._make_one(zone) + resource_dict = { + "name": "test.example.com", + "type": "A", + "ttl": 3600, + "rrdatas": [], + "routingPolicy": {}, + } + + cleaned = changes._routing_policy_cleaner(resource_dict) + self.assertTrue("rrdatas" not in cleaned) + self.assertTrue("routingPolicy" not in cleaned) + + def test__routing_policy_cleaner_truthy(self): + conn = _Connection() + client = _Client(project=self.PROJECT, connection=conn) + zone = _Zone(client) + changes = self._make_one(zone) + resource_dict = { + "name": "test.example.com", + "type": "A", + "ttl": 3600, + "rrdatas": ["10.1.2.3"], + "routingPolicy": {"geo": {}}, + } + + cleaned = changes._routing_policy_cleaner(resource_dict) + self.assertTrue("rrdatas" in cleaned) + self.assertTrue("routingPolicy" in cleaned) + class _Zone(object): def __init__( diff --git a/tests/unit/test_resource_record_set.py b/tests/unit/test_resource_record_set.py index d0869d2..3c4f3f1 100644 --- a/tests/unit/test_resource_record_set.py +++ b/tests/unit/test_resource_record_set.py @@ -29,23 +29,31 @@ def test_ctor(self): zone = _Zone() rrs = self._make_one( - "test.example.com", "CNAME", 3600, ["www.example.com"], zone + "test.example.com", "CNAME", 3600, ["www.example.com"], {}, zone ) self.assertEqual(rrs.name, "test.example.com") self.assertEqual(rrs.record_type, "CNAME") self.assertEqual(rrs.ttl, 3600) self.assertEqual(rrs.rrdatas, ["www.example.com"]) + self.assertEqual(rrs.routing_policy, {}) self.assertIs(rrs.zone, zone) def test_from_api_repr_missing_rrdatas(self): zone = _Zone() klass = self._get_target_class() - with self.assertRaises(KeyError): - klass.from_api_repr( - {"name": "test.example.com", "type": "CNAME", "ttl": 3600}, zone=zone - ) + rrs = klass.from_api_repr( + { + "name": "test.example.com", + "type": "CNAME", + "ttl": 3600, + "routingPolicy": {}, + }, + zone=zone, + ) + self.assertTrue(hasattr(rrs, "rrdatas")) + self.assertEqual(rrs.rrdatas, []) def test_from_api_repr_missing_ttl(self): zone = _Zone() @@ -57,6 +65,7 @@ def test_from_api_repr_missing_ttl(self): "name": "test.example.com", "type": "CNAME", "rrdatas": ["www.example.com"], + "routingPolicy": {}, }, zone=zone, ) @@ -71,6 +80,7 @@ def test_from_api_repr_missing_type(self): "name": "test.example.com", "ttl": 3600, "rrdatas": ["www.example.com"], + "routingPolicy": {}, }, zone=zone, ) @@ -81,10 +91,30 @@ def test_from_api_repr_missing_name(self): with self.assertRaises(KeyError): klass.from_api_repr( - {"type": "CNAME", "ttl": 3600, "rrdatas": ["www.example.com"]}, + { + "type": "CNAME", + "ttl": 3600, + "rrdatas": ["www.example.com"], + "routingPolicy": {}, + }, zone=zone, ) + def test_from_api_repr_missing_routing_policy(self): + zone = _Zone() + klass = self._get_target_class() + + rrs = klass.from_api_repr( + { + "name": "test.example.com", + "type": "CNAME", + "ttl": 3600, + "rrdatas": ["www.example.com"], + }, + zone=zone, + ) + self.assertEqual(rrs.routing_policy, {}) + def test_from_api_repr_bare(self): zone = _Zone() RESOURCE = { @@ -93,6 +123,7 @@ def test_from_api_repr_bare(self): "type": "CNAME", "ttl": "3600", "rrdatas": ["www.example.com"], + "routingPolicy": {}, } klass = self._get_target_class() rrs = klass.from_api_repr(RESOURCE, zone=zone) @@ -101,6 +132,7 @@ def test_from_api_repr_bare(self): self.assertEqual(rrs.ttl, 3600) self.assertEqual(rrs.rrdatas, ["www.example.com"]) self.assertIs(rrs.zone, zone) + self.assertEqual(rrs.routing_policy, {}) class _Zone(object): diff --git a/tests/unit/test_zone.py b/tests/unit/test_zone.py index 2b240bb..d7c4dc1 100644 --- a/tests/unit/test_zone.py +++ b/tests/unit/test_zone.py @@ -68,6 +68,7 @@ def _make_resource(self): "ns-cloud1.googledomains.com", "ns-cloud2.googledomains.com", ], + "routingPolicy": {}, } def _verifyReadonlyResourceProperties(self, zone, resource): @@ -194,9 +195,10 @@ def test_resource_record_set(self): RRS_TYPE = "CNAME" TTL = 3600 RRDATAS = ["www.example.com"] + ROUTING_POLICY = {} client = _Client(self.PROJECT) zone = self._make_one(self.ZONE_NAME, self.DNS_NAME, client) - rrs = zone.resource_record_set(RRS_NAME, RRS_TYPE, TTL, RRDATAS) + rrs = zone.resource_record_set(RRS_NAME, RRS_TYPE, TTL, RRDATAS, ROUTING_POLICY) self.assertIsInstance(rrs, ResourceRecordSet) self.assertEqual(rrs.name, RRS_NAME) self.assertEqual(rrs.record_type, RRS_TYPE) @@ -433,6 +435,7 @@ def test_list_resource_record_sets_defaults(self): "type": TYPE_1, "ttl": TTL_1, "rrdatas": RRDATAS_1, + "routingPolicy": {}, }, { "kind": "dns#resourceRecordSet", @@ -440,6 +443,7 @@ def test_list_resource_record_sets_defaults(self): "type": TYPE_2, "ttl": TTL_2, "rrdatas": RRDATAS_2, + "routingPolicy": {}, }, ], } @@ -488,6 +492,7 @@ def test_list_resource_record_sets_explicit(self): "type": TYPE_1, "ttl": TTL_1, "rrdatas": RRDATAS_1, + "routingPolicy": {}, }, { "kind": "dns#resourceRecordSet", @@ -495,6 +500,7 @@ def test_list_resource_record_sets_explicit(self): "type": TYPE_2, "ttl": TTL_2, "rrdatas": RRDATAS_2, + "routingPolicy": {}, }, ] } @@ -553,6 +559,7 @@ def _get_changes(self, token, changes_name): "type": type_1, "ttl": ttl_1, "rrdatas": rrdatas_1, + "routingPolicy": {}, } ], "deletions": [ @@ -562,6 +569,7 @@ def _get_changes(self, token, changes_name): "type": type_2, "ttl": ttl_2, "rrdatas": rrdatas_2, + "routingPolicy": {}, } ], }