Add v1 quotas and records for Designate
Clients are refactored to put common initialization in the new DesignateClient base class. Change-Id: Icf760442156789a386abeb128d8e71979805e04c
This commit is contained in:
parent
5e1a70b4b6
commit
87f4ddc194
29
cloudcafe/designate/client.py
Normal file
29
cloudcafe/designate/client.py
Normal file
@ -0,0 +1,29 @@
|
||||
"""
|
||||
Copyright 2014 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
from cafe.engine.http.client import AutoMarshallingHTTPClient
|
||||
|
||||
|
||||
class DesignateClient(AutoMarshallingHTTPClient):
|
||||
|
||||
def __init__(self, url, serialize_format, deserialize_format):
|
||||
super(DesignateClient, self).__init__(serialize_format,
|
||||
deserialize_format)
|
||||
self.url = url.rstrip('/')
|
||||
self.default_headers['Content-Type'] = 'application/{0}'.format(
|
||||
self.serialize_format)
|
||||
self.default_headers['Accept'] = 'application/{0}'.format(
|
||||
self.deserialize_format)
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
from cafe.engine.clients.rest import AutoMarshallingRestClient
|
||||
from cloudcafe.designate.client import DesignateClient
|
||||
from cloudcafe.designate.v1.domain_api.models.requests import DomainRequest
|
||||
from cloudcafe.designate.v1.domain_api.models.responses import (
|
||||
DomainResponse, DomainListResponse)
|
||||
@ -22,17 +22,12 @@ from cloudcafe.designate.v1.server_api.models.responses import (
|
||||
ServerResponse, ServerListResponse)
|
||||
|
||||
|
||||
class DomainAPIClient(AutoMarshallingRestClient):
|
||||
class DomainAPIClient(DesignateClient):
|
||||
|
||||
def __init__(self, url, serialize_format=None,
|
||||
deserialize_format=None):
|
||||
super(DomainAPIClient, self).__init__(serialize_format,
|
||||
super(DomainAPIClient, self).__init__(url, serialize_format,
|
||||
deserialize_format)
|
||||
self.url = url.rstrip('/')
|
||||
self.default_headers['Content-Type'] = 'application/{0}'.format(
|
||||
self.serialize_format)
|
||||
self.default_headers['Accept'] = 'application/{0}'.format(
|
||||
self.serialize_format)
|
||||
|
||||
def _get_domains_url(self):
|
||||
return "{0}/domains".format(self.url)
|
||||
|
15
cloudcafe/designate/v1/quotas_api/__init__.py
Normal file
15
cloudcafe/designate/v1/quotas_api/__init__.py
Normal file
@ -0,0 +1,15 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
57
cloudcafe/designate/v1/quotas_api/client.py
Normal file
57
cloudcafe/designate/v1/quotas_api/client.py
Normal file
@ -0,0 +1,57 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
from cloudcafe.designate.client import DesignateClient
|
||||
from cloudcafe.designate.v1.quotas_api.models.requests import QuotasRequest
|
||||
from cloudcafe.designate.v1.quotas_api.models.responses import QuotasResponse
|
||||
|
||||
|
||||
class QuotasAPIClient(DesignateClient):
|
||||
|
||||
def __init__(self, url, serialize_format=None, deserialize_format=None):
|
||||
super(QuotasAPIClient, self).__init__(url, serialize_format,
|
||||
deserialize_format)
|
||||
|
||||
def _get_quotas_url(self):
|
||||
return "{0}/quotas".format(self.url)
|
||||
|
||||
def _get_quota_url(self, tenant_id):
|
||||
return "{0}/{1}".format(self._get_quotas_url(), tenant_id)
|
||||
|
||||
def update_quotas(self, tenant_id=None, domains=None,
|
||||
recordset_records=None, domain_records=None,
|
||||
domain_recordsets=None, **requestslib_kwargs):
|
||||
"""PUT /quotas/{tenantID}"""
|
||||
quota_req = QuotasRequest(domains=domains,
|
||||
recordset_records=recordset_records,
|
||||
domain_records=domain_records,
|
||||
domain_recordsets=domain_recordsets)
|
||||
url = self._get_quota_url(tenant_id)
|
||||
return self.request('PUT', url, response_entity_type=QuotasResponse,
|
||||
request_entity=quota_req,
|
||||
requestslib_kwargs=requestslib_kwargs)
|
||||
|
||||
def get_quotas(self, tenant_id, **requestslib_kwargs):
|
||||
"""GET /quotas/{tenantID}"""
|
||||
url = self._get_quota_url(tenant_id)
|
||||
return self.request('GET', url, response_entity_type=QuotasResponse,
|
||||
requestslib_kwargs=requestslib_kwargs)
|
||||
|
||||
def delete_quotas(self, tenant_id, **requestslib_kwargs):
|
||||
"""DELETE /quotas/{tenantID}"""
|
||||
url = self._get_quota_url(tenant_id)
|
||||
return self.request('DELETE', url, response_entity_type=QuotasResponse,
|
||||
requestslib_kwargs=requestslib_kwargs)
|
15
cloudcafe/designate/v1/quotas_api/models/__init__.py
Normal file
15
cloudcafe/designate/v1/quotas_api/models/__init__.py
Normal file
@ -0,0 +1,15 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
38
cloudcafe/designate/v1/quotas_api/models/requests.py
Normal file
38
cloudcafe/designate/v1/quotas_api/models/requests.py
Normal file
@ -0,0 +1,38 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
from cafe.engine.models.base import AutoMarshallingModel
|
||||
|
||||
|
||||
class QuotasRequest(AutoMarshallingModel):
|
||||
|
||||
def __init__(self, domains=None, recordset_records=None,
|
||||
domain_records=None, domain_recordsets=None):
|
||||
self.domains = domains
|
||||
self.recordset_records = recordset_records
|
||||
self.domain_records = domain_records
|
||||
self.domain_recordsets = domain_recordsets
|
||||
|
||||
def _obj_to_json(self):
|
||||
return json.dumps(self._obj_to_dict())
|
||||
|
||||
def _obj_to_dict(self):
|
||||
return {"domain_records": self.domain_records,
|
||||
"domain_recordsets": self.domain_recordsets,
|
||||
"domains": self.domains,
|
||||
"recordset_records": self.recordset_records}
|
37
cloudcafe/designate/v1/quotas_api/models/responses.py
Normal file
37
cloudcafe/designate/v1/quotas_api/models/responses.py
Normal file
@ -0,0 +1,37 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
from cafe.engine.models.base import AutoMarshallingModel
|
||||
|
||||
|
||||
class QuotasResponse(AutoMarshallingModel):
|
||||
|
||||
def __init__(self, domains=None, recordset_records=None,
|
||||
domain_records=None, domain_recordsets=None):
|
||||
self.domains = domains
|
||||
self.recordset_records = recordset_records
|
||||
self.domain_records = domain_records
|
||||
self.domain_recordsets = domain_recordsets
|
||||
|
||||
@classmethod
|
||||
def _json_to_obj(cls, serialized_str):
|
||||
response_json = json.loads(serialized_str)
|
||||
return QuotasResponse(response_json.get('domains'),
|
||||
response_json.get('recordset_records'),
|
||||
response_json.get('domains_records'),
|
||||
response_json.get('domains_recordsets'))
|
15
cloudcafe/designate/v1/record_api/__init__.py
Normal file
15
cloudcafe/designate/v1/record_api/__init__.py
Normal file
@ -0,0 +1,15 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
79
cloudcafe/designate/v1/record_api/client.py
Normal file
79
cloudcafe/designate/v1/record_api/client.py
Normal file
@ -0,0 +1,79 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
from cloudcafe.designate.client import DesignateClient
|
||||
from cloudcafe.designate.v1.record_api.models.requests import RecordRequest
|
||||
from cloudcafe.designate.v1.record_api.models.responses import (
|
||||
RecordResponse, RecordListResponse)
|
||||
|
||||
|
||||
class RecordsAPIClient(DesignateClient):
|
||||
|
||||
def __init__(self, url, serialize_format=None,
|
||||
deserialize_format=None):
|
||||
super(RecordsAPIClient, self).__init__(url, serialize_format,
|
||||
deserialize_format)
|
||||
|
||||
def _get_domain_url(self, domain_id):
|
||||
return "{0}/domains/{1}".format(self.url, domain_id)
|
||||
|
||||
def _get_records_url(self, domain_id):
|
||||
return "{0}/records".format(self._get_domain_url(domain_id))
|
||||
|
||||
def _get_record_url(self, domain_id, record_id):
|
||||
return "{0}/{1}".format(self._get_records_url(domain_id), record_id)
|
||||
|
||||
def create_record(self, name=None, type=None,
|
||||
data=None, priority=None,
|
||||
domain_id=None, requestslib_kwargs=None):
|
||||
"""POST /domains/{domainID}/records"""
|
||||
record_req = RecordRequest(name=name, data=data, record_type=type,
|
||||
priority=priority)
|
||||
url = self._get_records_url(domain_id)
|
||||
return self.request('POST', url, request_entity=record_req,
|
||||
response_entity_type=RecordResponse,
|
||||
requestslib_kwargs=requestslib_kwargs)
|
||||
|
||||
def list_records(self, domain_id, requestslib_kwargs=None):
|
||||
"""GET /domains/{domainID}/records"""
|
||||
url = self._get_records_url(domain_id)
|
||||
return self.request('GET', url,
|
||||
response_entity_type=RecordListResponse,
|
||||
requestslib_kwargs=requestslib_kwargs)
|
||||
|
||||
def get_record(self, domain_id, record_id, requestslib_kwargs=None):
|
||||
"""GET /domains/{domainID}/records/{recordID}"""
|
||||
url = self._get_record_url(domain_id, record_id)
|
||||
return self.request('GET', url, response_entity_type=RecordResponse,
|
||||
requestslib_kwargs=requestslib_kwargs)
|
||||
|
||||
def update_record(self, domain_id=None, name=None, type=None, data=None,
|
||||
priority=None, record_id=None, requestslib_kwargs=None):
|
||||
"""PUT /domains/{domainID}/records/{record_id}"""
|
||||
record_req = RecordRequest(name=name, data=data,
|
||||
record_type=type, priority=priority)
|
||||
url = self._get_record_url(domain_id, record_id)
|
||||
return self.request('PUT', url,
|
||||
response_entity_type=RecordResponse,
|
||||
request_entity=record_req,
|
||||
requestslib_kwargs=requestslib_kwargs)
|
||||
|
||||
def delete_record(self, domain_id, record_id, requestslib_kwargs=None):
|
||||
"""DELETE /domains/{domainID}/records/{recordID}"""
|
||||
url = self._get_record_url(domain_id, record_id)
|
||||
return self.request('DELETE', url,
|
||||
response_entity_type=RecordResponse,
|
||||
requestslib_kwargs=requestslib_kwargs)
|
15
cloudcafe/designate/v1/record_api/models/__init__.py
Normal file
15
cloudcafe/designate/v1/record_api/models/__init__.py
Normal file
@ -0,0 +1,15 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
49
cloudcafe/designate/v1/record_api/models/requests.py
Normal file
49
cloudcafe/designate/v1/record_api/models/requests.py
Normal file
@ -0,0 +1,49 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
from cafe.engine.models.base import AutoMarshallingModel
|
||||
|
||||
|
||||
class RecordRequest(AutoMarshallingModel):
|
||||
|
||||
def __init__(self, name=None, record_type=None, data=None, ttl=None,
|
||||
priority=None):
|
||||
self.name = name
|
||||
self.type = record_type
|
||||
self.data = data
|
||||
self.ttl = ttl
|
||||
self.priority = priority
|
||||
|
||||
def _obj_to_json(self):
|
||||
records = self._obj_to_dict()
|
||||
return json.dumps(records)
|
||||
|
||||
def _obj_to_dict(self):
|
||||
"""
|
||||
{ "name": "www.example.com.",
|
||||
"type": "A",
|
||||
"data": "192.0.2.3" }
|
||||
"""
|
||||
records = {
|
||||
"name": self.name,
|
||||
"type": self.type,
|
||||
"data": self.data,
|
||||
"ttl": self.ttl,
|
||||
"priority": self.priority,
|
||||
}
|
||||
return self._remove_empty_values(records)
|
86
cloudcafe/designate/v1/record_api/models/responses.py
Normal file
86
cloudcafe/designate/v1/record_api/models/responses.py
Normal file
@ -0,0 +1,86 @@
|
||||
"""
|
||||
Copyright 2013 Rackspace
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
from cafe.engine.models.base import AutoMarshallingModel
|
||||
from cafe.engine.models.base import AutoMarshallingListModel
|
||||
|
||||
|
||||
class RecordResponse(AutoMarshallingModel):
|
||||
|
||||
def __init__(self, id=None, name=None, type=None, created_at=None,
|
||||
updated_at=None, domain_id=None, tenant_id=None, ttl=None,
|
||||
priority=None, data=None, description=None, version=None):
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.type = type
|
||||
self.ttl = ttl
|
||||
self.created_at = created_at
|
||||
self.updated_at = updated_at
|
||||
self.data = data
|
||||
self.domain_id = domain_id
|
||||
self.tenant_id = tenant_id
|
||||
self.priority = priority
|
||||
self.description = description
|
||||
self.version = version
|
||||
|
||||
@classmethod
|
||||
def _from_dict(cls, record_dict):
|
||||
"""
|
||||
{
|
||||
"id": "2e32e609-3a4f-45ba-bdef-e50eacd345ad",
|
||||
"name": "www.example.com.",
|
||||
"type": "A",
|
||||
"created_at": "2012-11-02T19:56:26.366792",
|
||||
"updated_at": null,
|
||||
"domain_id": "89acac79-38e7-497d-807c-a011e1310438",
|
||||
"ttl": null,
|
||||
"priority": null,
|
||||
"data": "192.0.2.3",
|
||||
"description": null
|
||||
}
|
||||
"""
|
||||
return RecordResponse(id = record_dict.get("id"),
|
||||
name = record_dict.get("name"),
|
||||
type = record_dict.get("type"),
|
||||
ttl = record_dict.get("ttl"),
|
||||
created_at = record_dict.get("created_at"),
|
||||
updated_at = record_dict.get("updated_at"),
|
||||
data = record_dict.get("data"),
|
||||
domain_id = record_dict.get("domain_id"),
|
||||
tenant_id = record_dict.get("tenant_id"),
|
||||
priority = record_dict.get("priority"),
|
||||
description = record_dict.get("description"),
|
||||
version = record_dict.get("version"))
|
||||
|
||||
@classmethod
|
||||
def _json_to_obj(cls, serialized_str):
|
||||
response_json = json.loads(serialized_str)
|
||||
return cls._from_dict(response_json)
|
||||
|
||||
|
||||
class RecordListResponse(AutoMarshallingListModel):
|
||||
|
||||
@classmethod
|
||||
def _json_to_obj(cls, serialized_str):
|
||||
response_json = json.loads(serialized_str)
|
||||
return cls._list_to_obj(response_json.get("records"))
|
||||
|
||||
@classmethod
|
||||
def _list_to_obj(cls, record_list):
|
||||
return RecordListResponse(
|
||||
[RecordResponse._from_dict(record) for record in record_list])
|
@ -14,23 +14,18 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
from cafe.engine.clients.rest import AutoMarshallingRestClient
|
||||
from cloudcafe.designate.client import DesignateClient
|
||||
from cloudcafe.designate.v1.server_api.models.requests import ServerRequest
|
||||
from cloudcafe.designate.v1.server_api.models.responses import \
|
||||
ServerResponse, ServerListResponse
|
||||
|
||||
|
||||
class ServerAPIClient(AutoMarshallingRestClient):
|
||||
class ServerAPIClient(DesignateClient):
|
||||
|
||||
def __init__(self, url, serialize_format=None,
|
||||
deserialize_format=None):
|
||||
super(ServerAPIClient, self).__init__(serialize_format,
|
||||
super(ServerAPIClient, self).__init__(url, serialize_format,
|
||||
deserialize_format)
|
||||
self.url = url.rstrip('/')
|
||||
self.default_headers['Content-Type'] = 'application/{0}'.format(
|
||||
self.serialize_format)
|
||||
self.default_headers['Accept'] = 'application/{0}'.format(
|
||||
self.serialize_format)
|
||||
|
||||
def _get_servers_url(self):
|
||||
return "{0}/servers".format(self.url)
|
||||
|
Loading…
x
Reference in New Issue
Block a user