Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4c3dbfa

Browse files
committed
Add 'Changes' resource type.
API methods to follow.
1 parent c4602c3 commit 4c3dbfa

File tree

2 files changed

+286
-0
lines changed

2 files changed

+286
-0
lines changed

gcloud/dns/changes.py

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Copyright 2015 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Define API ResourceRecordSets."""
16+
17+
import datetime
18+
19+
from gcloud._helpers import UTC
20+
from gcloud._helpers import _RFC3339_MICROS
21+
from gcloud.dns.resource_record_set import ResourceRecordSet
22+
23+
24+
class Changes(object):
25+
"""Changes are bundled additions / deletions of DNS resource records.
26+
27+
Changes are contained wihin a :class:`gcloud.dns.zone.ManagedZone`
28+
instance.
29+
30+
See:
31+
https://cloud.google.com/dns/api/v1/changes
32+
33+
:type zone: :class:`gcloud.dns.zone.ManagedZone`
34+
:param zone: A zone which holds one or more record sets.
35+
"""
36+
37+
def __init__(self, zone):
38+
self.zone = zone
39+
self._properties = {}
40+
self._additions = self._deletions = ()
41+
42+
@classmethod
43+
def from_api_repr(cls, resource, zone):
44+
"""Factory: construct a change set given its API representation
45+
46+
:type resource: dict
47+
:param resource: change set representation returned from the API
48+
49+
:type zone: :class:`gcloud.dns.zone.ManagedZone`
50+
:param zone: A zone which holds zero or more change sets.
51+
52+
:rtype: :class:`gcloud.dns.changes.Changes`
53+
:returns: RRS parsed from ``resource``.
54+
"""
55+
changes = cls(zone=zone)
56+
changes._additions = tuple([
57+
ResourceRecordSet.from_api_repr(added_res, zone)
58+
for added_res in resource.pop('additions', ())])
59+
changes._deletions = tuple([
60+
ResourceRecordSet.from_api_repr(added_res, zone)
61+
for added_res in resource.pop('deletions', ())])
62+
changes._properties = resource
63+
return changes
64+
65+
@property
66+
def name(self):
67+
"""Name of the change set.
68+
69+
:rtype: string or ``NoneType``
70+
:returns: Name, as set by the back-end, or None.
71+
"""
72+
return self._properties.get('id')
73+
74+
@property
75+
def status(self):
76+
"""Status of the change set.
77+
78+
:rtype: string or ``NoneType``
79+
:returns: Status, as set by the back-end, or None.
80+
"""
81+
return self._properties.get('status')
82+
83+
@property
84+
def started(self):
85+
"""Time when the change set was started.
86+
87+
:rtype: ``datetime.datetime`` or ``NoneType``
88+
:returns: Time, as set by the back-end, or None.
89+
"""
90+
stamp = self._properties.get('startTime')
91+
if stamp is not None:
92+
return datetime.datetime.strptime(stamp, _RFC3339_MICROS).replace(
93+
tzinfo=UTC)
94+
95+
@property
96+
def additions(self):
97+
"""Resource record sets to be added to the zone.
98+
99+
:rtype: sequence of
100+
:class:`gcloud.dns.resource_record_set.ResourceRecordSet'.
101+
:returns: record sets appended via :meth:`add_record_set`
102+
"""
103+
return self._additions
104+
105+
@property
106+
def deletions(self):
107+
"""Resource record sets to be deleted from the zone.
108+
109+
:rtype: sequence of
110+
:class:`gcloud.dns.resource_record_set.ResourceRecordSet'.
111+
:returns: record sets appended via :meth:`delete_record_set`
112+
"""
113+
return self._deletions
114+
115+
def add_record_set(self, record_set):
116+
"""Append a record set to the 'additions' for the change set.
117+
118+
:type record_set:
119+
:class:`gcloud.dns.resource_record_set.ResourceRecordSet'
120+
:param record_set: the record set to append
121+
122+
:raises: ``ValueError`` if ``record_set`` is not of the required type.
123+
"""
124+
if not isinstance(record_set, ResourceRecordSet):
125+
raise ValueError("Pass a ResourceRecordSet")
126+
self._additions += (record_set,)
127+
128+
def delete_record_set(self, record_set):
129+
"""Append a record set to the 'deletions' for the change set.
130+
131+
:type record_set:
132+
:class:`gcloud.dns.resource_record_set.ResourceRecordSet'
133+
:param record_set: the record set to append
134+
135+
:raises: ``ValueError`` if ``record_set`` is not of the required type.
136+
"""
137+
if not isinstance(record_set, ResourceRecordSet):
138+
raise ValueError("Pass a ResourceRecordSet")
139+
self._deletions += (record_set,)

gcloud/dns/test_changes.py

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# Copyright 2015 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import unittest2
16+
17+
18+
class TestChanges(unittest2.TestCase):
19+
20+
def _getTargetClass(self):
21+
from gcloud.dns.changes import Changes
22+
return Changes
23+
24+
def _makeOne(self, *args, **kw):
25+
return self._getTargetClass()(*args, **kw)
26+
27+
def test_ctor(self):
28+
zone = _Zone()
29+
30+
changes = self._makeOne(zone)
31+
32+
self.assertTrue(changes.zone is zone)
33+
self.assertEqual(changes.name, None)
34+
self.assertEqual(changes.status, None)
35+
self.assertEqual(changes.started, None)
36+
self.assertEqual(list(changes.additions), [])
37+
self.assertEqual(list(changes.deletions), [])
38+
39+
def test_from_api_repr_missing_additions_deletions(self):
40+
from gcloud._helpers import UTC
41+
from gcloud._helpers import _NOW
42+
from gcloud._helpers import _RFC3339_MICROS
43+
zone = _Zone()
44+
NAME = 'CHANGES_ID'
45+
WHEN = _NOW().replace(tzinfo=UTC)
46+
WHEN_STR = WHEN.strftime(_RFC3339_MICROS)
47+
RESOURCE = {
48+
'kind': 'dns#change',
49+
'id': NAME,
50+
'status': 'pending',
51+
'startTime': WHEN_STR,
52+
}
53+
zone = _Zone()
54+
klass = self._getTargetClass()
55+
changes = klass.from_api_repr(RESOURCE, zone=zone)
56+
57+
self.assertEqual(changes.name, NAME)
58+
self.assertEqual(changes.started, WHEN)
59+
self.assertEqual(changes.status, 'pending')
60+
61+
self.assertEqual(len(changes.additions), 0)
62+
self.assertEqual(len(changes.deletions), 0)
63+
64+
def test_from_api_repr(self):
65+
from gcloud._helpers import UTC
66+
from gcloud._helpers import _NOW
67+
from gcloud._helpers import _RFC3339_MICROS
68+
NAME = 'CHANGES_ID'
69+
WHEN = _NOW().replace(tzinfo=UTC)
70+
WHEN_STR = WHEN.strftime(_RFC3339_MICROS)
71+
RESOURCE = {
72+
'kind': 'dns#change',
73+
'id': NAME,
74+
'startTime': WHEN_STR,
75+
'status': 'done',
76+
'additions' : [
77+
{'name': 'test.example.com',
78+
'type': 'CNAME',
79+
'ttl': '3600',
80+
'rrdatas': ['www.example.com']},
81+
],
82+
'deletions': [
83+
{'name': 'test.example.com',
84+
'type': 'CNAME',
85+
'ttl': '86400',
86+
'rrdatas': ['other.example.com']},
87+
],
88+
}
89+
zone = _Zone()
90+
klass = self._getTargetClass()
91+
changes = klass.from_api_repr(RESOURCE, zone=zone)
92+
93+
self.assertEqual(changes.name, NAME)
94+
self.assertEqual(changes.started, WHEN)
95+
self.assertEqual(changes.status, 'done')
96+
97+
self.assertEqual(len(changes.additions), 1)
98+
rrs = changes.additions[0]
99+
self.assertEqual(rrs.name, 'test.example.com')
100+
self.assertEqual(rrs.record_type, 'CNAME')
101+
self.assertEqual(rrs.ttl, 3600)
102+
self.assertEqual(rrs.rrdatas, ['www.example.com'])
103+
self.assertTrue(rrs.zone is zone)
104+
105+
self.assertEqual(len(changes.deletions), 1)
106+
rrs = changes.deletions[0]
107+
self.assertEqual(rrs.name, 'test.example.com')
108+
self.assertEqual(rrs.record_type, 'CNAME')
109+
self.assertEqual(rrs.ttl, 86400)
110+
self.assertEqual(rrs.rrdatas, ['other.example.com'])
111+
self.assertTrue(rrs.zone is zone)
112+
113+
def test_add_record_set_invalid_value(self):
114+
zone = _Zone()
115+
changes = self._makeOne(zone)
116+
117+
with self.assertRaises(ValueError):
118+
changes.add_record_set(object())
119+
120+
def test_add_record_set(self):
121+
from gcloud.dns.resource_record_set import ResourceRecordSet
122+
zone = _Zone()
123+
changes = self._makeOne(zone)
124+
rrs = ResourceRecordSet('test.example.com', 'CNAME', 3600,
125+
['www.example.com'], zone)
126+
changes.add_record_set(rrs)
127+
self.assertEqual(list(changes.additions), [rrs])
128+
129+
def test_delete_record_set_invalid_value(self):
130+
zone = _Zone()
131+
changes = self._makeOne(zone)
132+
133+
with self.assertRaises(ValueError):
134+
changes.delete_record_set(object())
135+
136+
def test_delete_record_set(self):
137+
from gcloud.dns.resource_record_set import ResourceRecordSet
138+
zone = _Zone()
139+
changes = self._makeOne(zone)
140+
rrs = ResourceRecordSet('test.example.com', 'CNAME', 3600,
141+
['www.example.com'], zone)
142+
changes.delete_record_set(rrs)
143+
self.assertEqual(list(changes.deletions), [rrs])
144+
145+
146+
class _Zone(object):
147+
pass

0 commit comments

Comments
 (0)