Retire Packaging Deb project repos
This commit is part of a series to retire the Packaging Deb project. Step 2 is to remove all content from the project repos, replacing it with a README notification where to find ongoing work, and how to recover the repo if needed at some future point (as in https://docs.openstack.org/infra/manual/drivers.html#retiring-a-project). Change-Id: I23a2ff2335d997b37d7d934bb0f782ad25760dd9
This commit is contained in:
26
.gitignore
vendored
26
.gitignore
vendored
@@ -1,26 +0,0 @@
|
||||
*.pyc
|
||||
*.dat
|
||||
TAGS
|
||||
*.egg
|
||||
*.egg-info
|
||||
.eggs
|
||||
build
|
||||
.coverage
|
||||
.tox
|
||||
cover
|
||||
venv
|
||||
.venv
|
||||
*.sublime-workspace
|
||||
*.sqlite
|
||||
var/*
|
||||
etc/*.conf
|
||||
etc/*.ini
|
||||
AUTHORS
|
||||
ChangeLog
|
||||
doc/source/reference/api/*
|
||||
doc/build/*
|
||||
dist
|
||||
designateclient/versioninfo
|
||||
.testrepository
|
||||
*.log
|
||||
.idea/
|
@@ -1,4 +0,0 @@
|
||||
[gerrit]
|
||||
host=review.openstack.org
|
||||
port=29418
|
||||
project=openstack/python-designateclient.git
|
10
.testr.conf
10
.testr.conf
@@ -1,10 +0,0 @@
|
||||
[DEFAULT]
|
||||
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
|
||||
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
|
||||
OS_LOG_CAPTURE=${OS_LOG_CAPTURE:-1} \
|
||||
OS_DEBUG=${OS_DEBUG:-1} \
|
||||
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-160} \
|
||||
${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./designateclient/tests} $LISTOPT $IDOPTION
|
||||
|
||||
test_id_option=--load-list $IDFILE
|
||||
test_list_option=--list
|
@@ -1,16 +0,0 @@
|
||||
If you would like to contribute to the development of OpenStack,
|
||||
you must follow the steps documented at:
|
||||
|
||||
http://docs.openstack.org/infra/manual/developers.html
|
||||
|
||||
Once those steps have been completed, changes to OpenStack
|
||||
should be submitted for review via the Gerrit tool, following
|
||||
the workflow documented at:
|
||||
|
||||
http://docs.openstack.org/infra/manual/developers.html#development-workflow
|
||||
|
||||
Pull requests submitted through GitHub will be ignored.
|
||||
|
||||
Bugs should be filed on Launchpad, not GitHub:
|
||||
|
||||
https://bugs.launchpad.net/python-designateclient
|
176
LICENSE
176
LICENSE
@@ -1,176 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
14
README
Normal file
14
README
Normal file
@@ -0,0 +1,14 @@
|
||||
This project is no longer maintained.
|
||||
|
||||
The contents of this repository are still available in the Git
|
||||
source code management system. To see the contents of this
|
||||
repository before it reached its end of life, please check out the
|
||||
previous commit with "git checkout HEAD^1".
|
||||
|
||||
For ongoing work on maintaining OpenStack packages in the Debian
|
||||
distribution, please see the Debian OpenStack packaging team at
|
||||
https://wiki.debian.org/OpenStack/.
|
||||
|
||||
For any further questions, please email
|
||||
openstack-dev@lists.openstack.org or join #openstack-dev on
|
||||
Freenode.
|
42
README.rst
42
README.rst
@@ -1,42 +0,0 @@
|
||||
========================
|
||||
Team and repository tags
|
||||
========================
|
||||
|
||||
.. image:: http://governance.openstack.org/badges/python-designateclient.svg
|
||||
:target: http://governance.openstack.org/reference/tags/index.html
|
||||
|
||||
.. Change things from this point on
|
||||
|
||||
Python bindings to the Designate API
|
||||
=====================================
|
||||
|
||||
.. image:: https://img.shields.io/pypi/v/python-designateclient.svg
|
||||
:target: https://pypi.python.org/pypi/python-designateclient/
|
||||
:alt: Latest Version
|
||||
|
||||
.. image:: https://img.shields.io/pypi/dm/python-designateclient.svg
|
||||
:target: https://pypi.python.org/pypi/python-designateclient/
|
||||
:alt: Downloads
|
||||
|
||||
This is a client library for Designate built on the Designate API. It
|
||||
provides a Python API (the ``designateclient`` module) and a command-line tool
|
||||
(``designate``).
|
||||
|
||||
Development takes place via the usual OpenStack processes as outlined in the
|
||||
`developer guide <http://docs.openstack.org/infra/manual/developers.html>`_. The master
|
||||
repository is in `Git <http://git.openstack.org/cgit/openstack/python-designateclient>`_.
|
||||
|
||||
See release notes and more at `<http://docs.openstack.org/developer/python-designateclient/>`_.
|
||||
|
||||
* License: Apache License, Version 2.0
|
||||
* `PyPi`_ - package installation
|
||||
* `Online Documentation`_
|
||||
* `Bugs`_ - issue tracking
|
||||
* `Source`_
|
||||
* `How to Contribute`_
|
||||
|
||||
.. _PyPi: https://pypi.python.org/pypi/python-designateclient
|
||||
.. _Online Documentation: http://docs.openstack.org/developer/python-designateclient
|
||||
.. _Bugs: https://bugs.launchpad.net/python-designateclient
|
||||
.. _Source: https://git.openstack.org/cgit/openstack/python-designateclient
|
||||
.. _How to Contribute: http://docs.openstack.org/infra/manual/developers.html
|
@@ -1,21 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 sys
|
||||
from designateclient.shell import DesignateShell
|
||||
|
||||
shell = DesignateShell()
|
||||
sys.exit(shell.run(sys.argv[1:]))
|
@@ -1,19 +0,0 @@
|
||||
# Copyright 2017 Huawei, Inc. All rights reserved.
|
||||
#
|
||||
# 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 designateclient import version
|
||||
|
||||
|
||||
__version__ = version.version_info.version_string()
|
@@ -1,139 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 abc
|
||||
import warnings
|
||||
|
||||
from keystoneauth1 import exceptions as ks_exceptions
|
||||
from osc_lib.command import command
|
||||
import six
|
||||
|
||||
from designateclient import exceptions
|
||||
from designateclient import utils
|
||||
from designateclient.v1 import Client
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class Command(command.Command):
|
||||
def run(self, parsed_args):
|
||||
|
||||
warnings.simplefilter('once', category=DeprecationWarning)
|
||||
warnings.warn(
|
||||
'The "designate" CLI is being deprecated in favour of the '
|
||||
'"openstack" CLI plugin. All designate API v2 commands are '
|
||||
'implemented there. When the v1 API is removed this CLI will '
|
||||
'stop functioning',
|
||||
DeprecationWarning)
|
||||
warnings.resetwarnings()
|
||||
warnings.simplefilter('ignore', category=DeprecationWarning)
|
||||
|
||||
self.client = Client(
|
||||
region_name=self.app.options.os_region_name,
|
||||
service_type=self.app.options.os_service_type,
|
||||
endpoint_type=self.app.options.os_endpoint_type,
|
||||
session=self.app.session,
|
||||
all_tenants=self.app.options.all_tenants,
|
||||
edit_managed=self.app.options.edit_managed,
|
||||
endpoint=self.app.options.os_endpoint)
|
||||
warnings.resetwarnings()
|
||||
try:
|
||||
return super(Command, self).run(parsed_args)
|
||||
except exceptions.RemoteError as e:
|
||||
columns = ['Code', 'Type']
|
||||
values = [e.code, e.type]
|
||||
|
||||
if e.message:
|
||||
columns.append('Message')
|
||||
values.append(e.message)
|
||||
|
||||
if e.errors:
|
||||
columns.append('Errors')
|
||||
values.append(e.errors)
|
||||
|
||||
self.error_output(parsed_args, columns, values)
|
||||
except ks_exceptions.EndpointNotFound as e:
|
||||
self.app.log.error('No endpoint was found. You must provide a '
|
||||
'username or user id via --os-username, '
|
||||
'--os-user-id, env[OS_USERNAME] or '
|
||||
'env[OS_USER_ID]')
|
||||
|
||||
return 1
|
||||
|
||||
def error_output(self, parsed_args, column_names, data):
|
||||
self.formatter.emit_one(column_names,
|
||||
data,
|
||||
self.app.stdout,
|
||||
parsed_args)
|
||||
self.app.log.error('The requested action did not complete '
|
||||
'successfully')
|
||||
|
||||
@abc.abstractmethod
|
||||
def execute(self, parsed_args):
|
||||
"""
|
||||
Execute something, this is since we overload self.take_action()
|
||||
in order to format the data
|
||||
|
||||
This method __NEEDS__ to be overloaded!
|
||||
|
||||
:param parsed_args: The parsed args that are given by take_action()
|
||||
"""
|
||||
|
||||
def post_execute(self, data):
|
||||
"""
|
||||
Format the results locally if needed, by default we just return data
|
||||
|
||||
:param data: Whatever is returned by self.execute()
|
||||
"""
|
||||
return data
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
results = self.execute(parsed_args)
|
||||
return self.post_execute(results)
|
||||
|
||||
def find_resourceid_by_name_or_id(self, resource_plural, name_or_id):
|
||||
resource_client = getattr(self.client, resource_plural)
|
||||
return utils.find_resourceid_by_name_or_id(resource_client, name_or_id)
|
||||
|
||||
|
||||
class ListCommand(Command, command.Lister):
|
||||
columns = None
|
||||
|
||||
def post_execute(self, results):
|
||||
if len(results) > 0:
|
||||
columns = self.columns or utils.get_columns(results)
|
||||
data = [utils.get_item_properties(i, columns) for i in results]
|
||||
return columns, data
|
||||
else:
|
||||
return [], ()
|
||||
|
||||
|
||||
class GetCommand(Command, command.ShowOne):
|
||||
def post_execute(self, results):
|
||||
return list(six.iterkeys(results)), list(six.itervalues(results))
|
||||
|
||||
|
||||
class CreateCommand(Command, command.ShowOne):
|
||||
def post_execute(self, results):
|
||||
return list(six.iterkeys(results)), list(six.itervalues(results))
|
||||
|
||||
|
||||
class UpdateCommand(Command, command.ShowOne):
|
||||
def post_execute(self, results):
|
||||
return list(six.iterkeys(results)), list(six.itervalues(results))
|
||||
|
||||
|
||||
class DeleteCommand(Command, command.ShowOne):
|
||||
def post_execute(self, results):
|
||||
return [], []
|
@@ -1,38 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 logging
|
||||
|
||||
from designateclient.cli import base
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PingCommand(base.GetCommand):
|
||||
"""Ping a service on a given host"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(PingCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('--service', help="Service name (e.g. central)",
|
||||
required=True)
|
||||
parser.add_argument('--host', help="Hostname", required=True)
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return self.client.diagnostics.ping(parsed_args.service,
|
||||
parsed_args.host)
|
@@ -1,144 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 logging
|
||||
|
||||
from designateclient.cli import base
|
||||
from designateclient.v1.domains import Domain
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ListDomainsCommand(base.ListCommand):
|
||||
"""List Domains"""
|
||||
|
||||
columns = ['id', 'name', 'serial']
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return self.client.domains.list()
|
||||
|
||||
|
||||
class GetDomainCommand(base.GetCommand):
|
||||
"""Get Domain"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(GetDomainCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Domain ID or name.")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
id = self.find_resourceid_by_name_or_id('domains', parsed_args.id)
|
||||
return self.client.domains.get(id)
|
||||
|
||||
|
||||
class CreateDomainCommand(base.CreateCommand):
|
||||
"""Create Domain"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateDomainCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('--name', help="Domain name.", required=True)
|
||||
parser.add_argument('--email', help="Domain email.", required=True)
|
||||
parser.add_argument('--ttl', type=int, help="Time to live (seconds).")
|
||||
parser.add_argument('--description', help="Description.")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
domain = Domain(
|
||||
name=parsed_args.name,
|
||||
email=parsed_args.email,
|
||||
)
|
||||
|
||||
if parsed_args.description:
|
||||
domain.description = parsed_args.description
|
||||
|
||||
if parsed_args.ttl is not None:
|
||||
domain.ttl = parsed_args.ttl
|
||||
|
||||
return self.client.domains.create(domain)
|
||||
|
||||
|
||||
class UpdateDomainCommand(base.UpdateCommand):
|
||||
"""Update Domain"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(UpdateDomainCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Domain ID or name.")
|
||||
parser.add_argument('--name', help="Domain name.")
|
||||
parser.add_argument('--email', help="Domain email.")
|
||||
parser.add_argument('--ttl', type=int, help="Time to live (seconds).")
|
||||
description_group = parser.add_mutually_exclusive_group()
|
||||
description_group.add_argument('--description', help="Description.")
|
||||
description_group.add_argument('--no-description', action='store_true')
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
# TODO(kiall): API needs updating.. this get is silly
|
||||
id = self.find_resourceid_by_name_or_id('domains', parsed_args.id)
|
||||
domain = self.client.domains.get(id)
|
||||
|
||||
if parsed_args.name:
|
||||
domain.name = parsed_args.name
|
||||
|
||||
if parsed_args.email:
|
||||
domain.email = parsed_args.email
|
||||
|
||||
if parsed_args.ttl is not None:
|
||||
domain.ttl = parsed_args.ttl
|
||||
|
||||
if parsed_args.no_description:
|
||||
domain.description = None
|
||||
elif parsed_args.description:
|
||||
domain.description = parsed_args.description
|
||||
|
||||
return self.client.domains.update(domain)
|
||||
|
||||
|
||||
class DeleteDomainCommand(base.DeleteCommand):
|
||||
"""Delete Domain"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteDomainCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Domain ID or name.")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
id = self.find_resourceid_by_name_or_id('domains', parsed_args.id)
|
||||
return self.client.domains.delete(id)
|
||||
|
||||
|
||||
class ListDomainServersCommand(base.ListCommand):
|
||||
"""List Domain Servers"""
|
||||
|
||||
columns = ['name']
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListDomainServersCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Domain ID or name.")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
id = self.find_resourceid_by_name_or_id('domains', parsed_args.id)
|
||||
return self.client.domains.list_domain_servers(id)
|
@@ -1,83 +0,0 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 logging
|
||||
|
||||
from designateclient.cli import base
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GetQuotaCommand(base.GetCommand):
|
||||
"""Get Quota"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(GetQuotaCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('tenant_id', help="Tenant ID")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return self.client.quotas.get(parsed_args.tenant_id)
|
||||
|
||||
|
||||
class UpdateQuotaCommand(base.UpdateCommand):
|
||||
"""Update Quota"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(UpdateQuotaCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('tenant_id', help="Tenant ID.")
|
||||
parser.add_argument('--domains', help="Allowed domains.", type=int)
|
||||
parser.add_argument('--domain-recordsets',
|
||||
help="Allowed domain records.",
|
||||
type=int)
|
||||
parser.add_argument('--recordset-records',
|
||||
help="Allowed recordset records.",
|
||||
type=int)
|
||||
parser.add_argument('--domain-records',
|
||||
help="Allowed domain records.",
|
||||
type=int)
|
||||
parser.add_argument('--api-export-size',
|
||||
help="Allowed zone export recordsets.",
|
||||
type=int)
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
# TODO(kiall): API needs updating.. this get is silly
|
||||
quota = self.client.quotas.get(parsed_args.tenant_id)
|
||||
|
||||
for key, old in quota.items():
|
||||
new = getattr(parsed_args, key)
|
||||
if new is not None and new != old:
|
||||
quota[key] = new
|
||||
return self.client.quotas.update(parsed_args.tenant_id, quota)
|
||||
|
||||
|
||||
class ResetQuotaCommand(base.DeleteCommand):
|
||||
"""Reset Quota"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ResetQuotaCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('tenant_id', help="Tenant ID.")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
self.client.quotas.reset(parsed_args.tenant_id)
|
@@ -1,187 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 logging
|
||||
|
||||
from designateclient.cli import base
|
||||
from designateclient.v1.records import Record
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ListRecordsCommand(base.ListCommand):
|
||||
"""List Records"""
|
||||
|
||||
columns = ['id', 'type', 'name', 'data']
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListRecordsCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('domain_id', help="Domain ID or name.")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
domain_id = self.find_resourceid_by_name_or_id(
|
||||
'domains', parsed_args.domain_id)
|
||||
return self.client.records.list(domain_id)
|
||||
|
||||
|
||||
class GetRecordCommand(base.GetCommand):
|
||||
"""Get Record"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(GetRecordCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('domain_id', help="Domain ID or name.")
|
||||
parser.add_argument('id', help="Record ID.")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
domain_id = self.find_resourceid_by_name_or_id(
|
||||
'domains', parsed_args.domain_id)
|
||||
return self.client.records.get(domain_id, parsed_args.id)
|
||||
|
||||
|
||||
class CreateRecordCommand(base.CreateCommand):
|
||||
"""Create Record"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateRecordCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('domain_id', help="Domain ID or name.")
|
||||
parser.add_argument(
|
||||
'--name', help="Record (relative|absolute) name.", required=True)
|
||||
parser.add_argument('--type', help="Record type.", required=True)
|
||||
parser.add_argument('--data', help="Record data.", required=True)
|
||||
parser.add_argument('--ttl', type=int, help="Record TTL.")
|
||||
parser.add_argument('--priority', type=int, help="Record priority.")
|
||||
parser.add_argument('--description', help="Description.")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
domain_id = self.find_resourceid_by_name_or_id(
|
||||
'domains', parsed_args.domain_id)
|
||||
|
||||
if not parsed_args.name.endswith('.'):
|
||||
# Relative name?
|
||||
domain_name = self.client.domains.get(domain_id)['name']
|
||||
absolute = parsed_args.name + '.'
|
||||
relative = absolute + domain_name
|
||||
if absolute.endswith('.' + domain_name):
|
||||
# Relative name or absolute name missing final period?
|
||||
msg = ('"%s" is a relative name but looks like an absolute '
|
||||
'name, use --name "%s" or "%s"'
|
||||
% (parsed_args.name, absolute, relative))
|
||||
raise ValueError(msg)
|
||||
parsed_args.name = relative
|
||||
|
||||
record = Record(
|
||||
name=parsed_args.name,
|
||||
type=parsed_args.type,
|
||||
data=parsed_args.data,
|
||||
)
|
||||
|
||||
if parsed_args.ttl is not None:
|
||||
record.ttl = parsed_args.ttl
|
||||
|
||||
if parsed_args.priority is not None:
|
||||
record.priority = parsed_args.priority
|
||||
|
||||
if parsed_args.description:
|
||||
record.description = parsed_args.description
|
||||
|
||||
return self.client.records.create(domain_id, record)
|
||||
|
||||
|
||||
class UpdateRecordCommand(base.UpdateCommand):
|
||||
"""Update Record"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(UpdateRecordCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('domain_id', help="Domain ID or name.")
|
||||
parser.add_argument('id', help="Record ID.")
|
||||
parser.add_argument('--name', help="Record name.")
|
||||
parser.add_argument('--type', help="Record type.")
|
||||
parser.add_argument('--data', help="Record data.")
|
||||
|
||||
description_group = parser.add_mutually_exclusive_group()
|
||||
description_group.add_argument('--description', help="Description.")
|
||||
description_group.add_argument('--no-description', action='store_true')
|
||||
|
||||
ttl_group = parser.add_mutually_exclusive_group()
|
||||
ttl_group.add_argument('--ttl', type=int,
|
||||
help="Record time to live (seconds).")
|
||||
ttl_group.add_argument('--no-ttl', action='store_true')
|
||||
|
||||
priotity_group = parser.add_mutually_exclusive_group()
|
||||
priotity_group.add_argument('--priority', type=int,
|
||||
help="Record priority.")
|
||||
priotity_group.add_argument('--no-priority', action='store_true')
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
# TODO(kiall): API needs updating.. this get is silly
|
||||
record = self.client.records.get(parsed_args.domain_id, parsed_args.id)
|
||||
|
||||
if parsed_args.name:
|
||||
record.name = parsed_args.name
|
||||
|
||||
if parsed_args.type:
|
||||
record.type = parsed_args.type
|
||||
|
||||
if parsed_args.data:
|
||||
record.data = parsed_args.data
|
||||
|
||||
if parsed_args.no_ttl:
|
||||
record.ttl = None
|
||||
elif parsed_args.ttl is not None:
|
||||
record.ttl = parsed_args.ttl
|
||||
|
||||
if parsed_args.no_priority:
|
||||
record.priority = None
|
||||
elif parsed_args.priority is not None:
|
||||
record.priority = parsed_args.priority
|
||||
|
||||
if parsed_args.no_description:
|
||||
record.description = None
|
||||
elif parsed_args.description:
|
||||
record.description = parsed_args.description
|
||||
|
||||
domain_id = self.find_resourceid_by_name_or_id(
|
||||
'domains', parsed_args.domain_id)
|
||||
return self.client.records.update(domain_id, record)
|
||||
|
||||
|
||||
class DeleteRecordCommand(base.DeleteCommand):
|
||||
"""Delete Record"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteRecordCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('domain_id', help="Domain ID or name.")
|
||||
parser.add_argument('id', help="Record ID.")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
domain_id = self.find_resourceid_by_name_or_id(
|
||||
'domains', parsed_args.domain_id)
|
||||
return self.client.records.delete(domain_id, parsed_args.id)
|
@@ -1,71 +0,0 @@
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P. All Rights Reserved.
|
||||
#
|
||||
# Author: Patrick Galbraith <patg@patg.net>
|
||||
#
|
||||
# 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 designateclient.cli import base
|
||||
|
||||
|
||||
class DomainCountCommand(base.GetCommand):
|
||||
"""Get counts for total domains"""
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return self.client.reports.count_domains()
|
||||
|
||||
|
||||
class RecordCountCommand(base.GetCommand):
|
||||
"""Get counts for total records"""
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return self.client.reports.count_records()
|
||||
|
||||
|
||||
class TenantCountCommand(base.GetCommand):
|
||||
"""Get counts for total tenants"""
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return self.client.reports.count_tenants()
|
||||
|
||||
|
||||
class CountsCommand(base.GetCommand):
|
||||
"""Get count totals for all tenants, domains and records"""
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return self.client.reports.count_all()
|
||||
|
||||
|
||||
class TenantsCommand(base.ListCommand):
|
||||
"""Get list of tenants and domain count for each"""
|
||||
|
||||
columns = ['domain_count', 'id']
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return self.client.reports.tenants_all()
|
||||
|
||||
|
||||
class TenantCommand(base.ListCommand):
|
||||
"""Get a list of domains for given tenant"""
|
||||
|
||||
columns = ['domain']
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(TenantCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('--report-tenant-id',
|
||||
help="The tenant_id being reported on.",
|
||||
required=True)
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return self.client.reports.tenant_domains(parsed_args.report_tenant_id)
|
@@ -1,98 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 logging
|
||||
|
||||
from designateclient.cli import base
|
||||
from designateclient.v1.servers import Server
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ListServersCommand(base.ListCommand):
|
||||
"""List Servers"""
|
||||
|
||||
columns = ['id', 'name']
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return self.client.servers.list()
|
||||
|
||||
|
||||
class GetServerCommand(base.GetCommand):
|
||||
"""Get Server"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(GetServerCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Server ID.")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return self.client.servers.get(parsed_args.id)
|
||||
|
||||
|
||||
class CreateServerCommand(base.CreateCommand):
|
||||
"""Create Server"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateServerCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('--name', help="Server name.", required=True)
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
server = Server(
|
||||
name=parsed_args.name,
|
||||
)
|
||||
|
||||
return self.client.servers.create(server)
|
||||
|
||||
|
||||
class UpdateServerCommand(base.UpdateCommand):
|
||||
"""Update Server"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(UpdateServerCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Server ID.")
|
||||
parser.add_argument('--name', help="Server name.")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
# TODO(kiall): API needs updating.. this get is silly
|
||||
server = self.client.servers.get(parsed_args.id)
|
||||
|
||||
if parsed_args.name:
|
||||
server.name = parsed_args.name
|
||||
|
||||
return self.client.servers.update(server)
|
||||
|
||||
|
||||
class DeleteServerCommand(base.DeleteCommand):
|
||||
"""Delete Server"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteServerCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Server ID.")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
return self.client.servers.delete(parsed_args.id)
|
@@ -1,63 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 logging
|
||||
|
||||
from designateclient.cli import base
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SyncAllCommand(base.DeleteCommand):
|
||||
"""Sync Everything"""
|
||||
|
||||
def execute(self, parsed_args):
|
||||
self.client.sync.sync_all()
|
||||
|
||||
LOG.info('Synchronization of all domains scheduled')
|
||||
|
||||
|
||||
class SyncDomainCommand(base.DeleteCommand):
|
||||
"""Sync a single Domain"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(SyncDomainCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('domain_id', help="Domain ID")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
self.client.sync.sync_domain(parsed_args.domain_id)
|
||||
|
||||
LOG.info('Synchronization of domain scheduled')
|
||||
|
||||
|
||||
class SyncRecordCommand(base.DeleteCommand):
|
||||
"""Sync a single Record"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(SyncRecordCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('domain_id', help="Domain ID")
|
||||
parser.add_argument('record_id', help="Record ID")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
self.client.sync.sync_record(parsed_args.domain_id,
|
||||
parsed_args.record_id)
|
||||
|
||||
LOG.info('Synchronization of record scheduled')
|
@@ -1,37 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 logging
|
||||
|
||||
from designateclient.cli import base
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TouchDomainCommand(base.DeleteCommand):
|
||||
"""Touch a single Domain"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(TouchDomainCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('domain_id', help="Domain ID")
|
||||
|
||||
return parser
|
||||
|
||||
def execute(self, parsed_args):
|
||||
self.client.touch.domain(parsed_args.domain_id)
|
||||
|
||||
LOG.info('Domain touched successfully')
|
@@ -1,135 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 abc
|
||||
import json
|
||||
|
||||
import six
|
||||
from six.moves.urllib import parse
|
||||
from stevedore import extension
|
||||
|
||||
from designateclient import exceptions
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class Controller(object):
|
||||
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
def build_url(self, url, criterion=None, marker=None, limit=None):
|
||||
params = criterion or {}
|
||||
|
||||
if marker is not None:
|
||||
params['marker'] = marker
|
||||
if limit is not None:
|
||||
params['limit'] = limit
|
||||
|
||||
q = parse.urlencode(params) if params else ''
|
||||
return '%(url)s%(params)s' % {
|
||||
'url': url,
|
||||
'params': '?%s' % q
|
||||
}
|
||||
|
||||
def _serialize(self, kwargs):
|
||||
headers = kwargs.get('headers')
|
||||
content_type = headers.get('Content-Type') if headers else None
|
||||
|
||||
if 'data' in kwargs and content_type in {None, 'application/json'}:
|
||||
kwargs['data'] = json.dumps(kwargs['data'])
|
||||
|
||||
def _post(self, url, response_key=None, **kwargs):
|
||||
self._serialize(kwargs)
|
||||
|
||||
resp, body = self.client.session.post(url, **kwargs)
|
||||
if response_key is not None:
|
||||
return body[response_key]
|
||||
return body
|
||||
|
||||
def _get(self, url, response_key=None):
|
||||
resp, body = self.client.session.get(url)
|
||||
if response_key is not None:
|
||||
return body[response_key]
|
||||
return body
|
||||
|
||||
def _patch(self, url, response_key=None, **kwargs):
|
||||
self._serialize(kwargs)
|
||||
|
||||
resp, body = self.client.session.patch(url, **kwargs)
|
||||
if response_key is not None:
|
||||
return body[response_key]
|
||||
return body
|
||||
|
||||
def _put(self, url, response_key=None, **kwargs):
|
||||
self._serialize(kwargs)
|
||||
|
||||
resp, body = self.client.session.put(url, **kwargs)
|
||||
if response_key is not None:
|
||||
return body[response_key]
|
||||
return body
|
||||
|
||||
def _delete(self, url, response_key=None, **kwargs):
|
||||
resp, body = self.client.session.delete(url, **kwargs)
|
||||
if response_key is not None:
|
||||
return body[response_key]
|
||||
return body
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class CrudController(Controller):
|
||||
|
||||
@abc.abstractmethod
|
||||
def list(self, *args, **kw):
|
||||
"""
|
||||
List a resource
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get(self, *args, **kw):
|
||||
"""
|
||||
Get a resource
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def create(self, *args, **kw):
|
||||
"""
|
||||
Create a resource
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def update(self, *args, **kw):
|
||||
"""
|
||||
Update a resource
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def delete(self, *args, **kw):
|
||||
"""
|
||||
Delete a resource
|
||||
"""
|
||||
|
||||
|
||||
def get_versions():
|
||||
mgr = extension.ExtensionManager('designateclient.versions')
|
||||
return dict([(ep.name, ep.plugin) for ep in mgr.extensions])
|
||||
|
||||
|
||||
def Client(version, *args, **kwargs): # noqa
|
||||
versions = get_versions()
|
||||
if version not in versions:
|
||||
msg = 'Version %s is not supported, use one of (%s)' % (
|
||||
version, list(six.iterkeys(versions)))
|
||||
raise exceptions.UnsupportedVersion(msg)
|
||||
return versions[version](*args, **kwargs)
|
@@ -1,84 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
class Base(Exception):
|
||||
def __init__(self, message=None):
|
||||
if not message:
|
||||
message = self.__class__.__name__
|
||||
super(Base, self).__init__(message)
|
||||
|
||||
|
||||
class UnsupportedVersion(Base):
|
||||
pass
|
||||
|
||||
|
||||
class ResourceNotFound(Base):
|
||||
pass
|
||||
|
||||
|
||||
class NoUniqueMatch(Base):
|
||||
pass
|
||||
|
||||
|
||||
class RemoteError(Base):
|
||||
def __init__(self, message=None, code=None, type=None, errors=None,
|
||||
request_id=None):
|
||||
err_message = self._get_error_message(message, type, errors)
|
||||
self.message = err_message
|
||||
self.code = code
|
||||
self.type = type
|
||||
self.errors = errors
|
||||
self.request_id = request_id
|
||||
|
||||
super(RemoteError, self).__init__(err_message)
|
||||
|
||||
def _get_error_message(self, _message, _type, _errors):
|
||||
# Try to get a useful error msg if 'message' has nothing
|
||||
if not _message:
|
||||
if _errors and 'errors' in _errors:
|
||||
err_msg = list()
|
||||
for err in _errors['errors']:
|
||||
if 'message' in err:
|
||||
err_msg.append(err['message'])
|
||||
_message = '. '.join(err_msg)
|
||||
elif _type:
|
||||
_message = str(_type)
|
||||
return _message
|
||||
|
||||
|
||||
class Unknown(RemoteError):
|
||||
pass
|
||||
|
||||
|
||||
class BadRequest(RemoteError):
|
||||
pass
|
||||
|
||||
|
||||
class Forbidden(RemoteError):
|
||||
pass
|
||||
|
||||
|
||||
class Conflict(RemoteError):
|
||||
pass
|
||||
|
||||
|
||||
class NotFound(RemoteError):
|
||||
pass
|
||||
|
||||
|
||||
class OverQuota(RemoteError):
|
||||
pass
|
@@ -1,7 +0,0 @@
|
||||
import logging
|
||||
|
||||
logging.basicConfig(
|
||||
filename='functional-tests.log',
|
||||
filemode='w',
|
||||
level=logging.DEBUG,
|
||||
)
|
@@ -1,46 +0,0 @@
|
||||
"""
|
||||
Copyright 2015 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 tempest.lib.cli import base
|
||||
from tempest.lib.exceptions import CommandFailed
|
||||
|
||||
from designateclient.functionaltests import client
|
||||
from designateclient.functionaltests import config
|
||||
|
||||
|
||||
class BaseDesignateTest(base.ClientTestBase):
|
||||
|
||||
def _get_clients(self):
|
||||
config.read_config()
|
||||
return client.DesignateCLI.as_user('default')
|
||||
|
||||
def ensure_tld_exists(self, tld):
|
||||
try:
|
||||
self.clients.as_user('admin').tld_create(tld)
|
||||
except CommandFailed:
|
||||
pass
|
||||
|
||||
def _is_entity_in_list(self, entity, entity_list):
|
||||
"""Determines if the given entity exists in the given list.
|
||||
|
||||
Uses the id for comparison.
|
||||
|
||||
Certain entities (e.g. zone import, export) cannot be made
|
||||
comparable in a list of CLI output results, because the fields
|
||||
in a list command can be different from those in a show command.
|
||||
|
||||
"""
|
||||
return any([entity_record.id == entity.id
|
||||
for entity_record in entity_list])
|
@@ -1,388 +0,0 @@
|
||||
"""
|
||||
Copyright 2015 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 logging
|
||||
import os
|
||||
|
||||
from tempest.lib.cli import base
|
||||
|
||||
from designateclient.functionaltests.config import cfg
|
||||
from designateclient.functionaltests.models import FieldValueModel
|
||||
from designateclient.functionaltests.models import ListModel
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def build_option_string(options):
|
||||
"""Format a string of option flags (--key 'value').
|
||||
|
||||
This will quote the values, in case spaces are included.
|
||||
Any values that are None are excluded entirely.
|
||||
|
||||
Usage::
|
||||
|
||||
build_option_string({
|
||||
"--email": "me@example.com",
|
||||
"--name": "example.com."
|
||||
"--ttl": None,
|
||||
|
||||
})
|
||||
|
||||
Returns::
|
||||
|
||||
"--email 'me@example.com' --name 'example.com.'
|
||||
"""
|
||||
return " ".join("{0} '{1}'".format(flag, value)
|
||||
for flag, value in options.items()
|
||||
if value is not None)
|
||||
|
||||
|
||||
def build_flags_string(flags):
|
||||
"""Format a string of value-less flags.
|
||||
|
||||
Pass in a dictionary mapping flags to booleans. Those flags set to true
|
||||
are included in the returned string.
|
||||
|
||||
Usage::
|
||||
|
||||
build_flags_string({
|
||||
'--no-ttl': True,
|
||||
'--no-name': False,
|
||||
'--verbose': True,
|
||||
})
|
||||
|
||||
Returns::
|
||||
|
||||
'--no-ttl --verbose'
|
||||
"""
|
||||
flags = {flag: is_set for flag, is_set in flags.items() if is_set}
|
||||
return " ".join(flags.keys())
|
||||
|
||||
|
||||
class ZoneCommands(object):
|
||||
"""This is a mixin that provides zone commands to DesignateCLI"""
|
||||
|
||||
def zone_list(self, *args, **kwargs):
|
||||
return self.parsed_cmd('zone list', ListModel, *args, **kwargs)
|
||||
|
||||
def zone_show(self, id, *args, **kwargs):
|
||||
return self.parsed_cmd('zone show %s' % id, FieldValueModel, *args,
|
||||
**kwargs)
|
||||
|
||||
def zone_delete(self, id, *args, **kwargs):
|
||||
return self.parsed_cmd('zone delete %s' % id, FieldValueModel, *args,
|
||||
**kwargs)
|
||||
|
||||
def zone_create(self, name, email=None, ttl=None, description=None,
|
||||
type=None, masters=None, *args, **kwargs):
|
||||
options_str = build_option_string({
|
||||
"--email": email,
|
||||
"--ttl": ttl,
|
||||
"--description": description,
|
||||
"--masters": masters,
|
||||
"--type": type,
|
||||
})
|
||||
cmd = 'zone create {0} {1}'.format(name, options_str)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
def zone_set(self, id, email=None, ttl=None, description=None,
|
||||
type=None, masters=None, *args, **kwargs):
|
||||
options_str = build_option_string({
|
||||
"--email": email,
|
||||
"--ttl": ttl,
|
||||
"--description": description,
|
||||
"--masters": masters,
|
||||
"--type": type,
|
||||
})
|
||||
cmd = 'zone set {0} {1}'.format(id, options_str)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
|
||||
class ZoneTransferCommands(object):
|
||||
"""A mixin for DesignateCLI to add zone transfer commands"""
|
||||
|
||||
def zone_transfer_request_list(self, *args, **kwargs):
|
||||
cmd = 'zone transfer request list'
|
||||
return self.parsed_cmd(cmd, ListModel, *args, **kwargs)
|
||||
|
||||
def zone_transfer_request_create(self, zone_id, target_project_id=None,
|
||||
description=None, *args, **kwargs):
|
||||
options_str = build_option_string({
|
||||
"--target-project-id": target_project_id,
|
||||
"--description": description,
|
||||
})
|
||||
cmd = 'zone transfer request create {0} {1}'.format(
|
||||
zone_id, options_str)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
def zone_transfer_request_show(self, id, *args, **kwargs):
|
||||
cmd = 'zone transfer request show {0}'.format(id)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
def zone_transfer_request_set(self, id, description=None, *args, **kwargs):
|
||||
options_str = build_option_string({"--description": description})
|
||||
cmd = 'zone transfer request set {0} {1}'.format(options_str, id)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
def zone_transfer_request_delete(self, id, *args, **kwargs):
|
||||
cmd = 'zone transfer request delete {0}'.format(id)
|
||||
return self.parsed_cmd(cmd, *args, **kwargs)
|
||||
|
||||
def zone_transfer_accept_request(self, id, key, *args, **kwargs):
|
||||
options_str = build_option_string({
|
||||
"--transfer-id": id,
|
||||
"--key": key,
|
||||
})
|
||||
cmd = 'zone transfer accept request {0}'.format(options_str)
|
||||
return self.parsed_cmd(cmd, *args, **kwargs)
|
||||
|
||||
def zone_transfer_accept_show(self, id, *args, **kwargs):
|
||||
cmd = 'zone transfer accept show {0}'.format(id)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
|
||||
class ZoneExportCommands(object):
|
||||
"""A mixin for DesignateCLI to add zone export commands"""
|
||||
|
||||
def zone_export_list(self, *args, **kwargs):
|
||||
cmd = 'zone export list'
|
||||
return self.parsed_cmd(cmd, ListModel, *args, **kwargs)
|
||||
|
||||
def zone_export_create(self, zone_id, *args, **kwargs):
|
||||
cmd = 'zone export create {0}'.format(
|
||||
zone_id)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
def zone_export_show(self, zone_export_id, *args, **kwargs):
|
||||
cmd = 'zone export show {0}'.format(zone_export_id)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
def zone_export_delete(self, zone_export_id, *args, **kwargs):
|
||||
cmd = 'zone export delete {0}'.format(zone_export_id)
|
||||
return self.parsed_cmd(cmd, *args, **kwargs)
|
||||
|
||||
def zone_export_showfile(self, zone_export_id, *args, **kwargs):
|
||||
cmd = 'zone export showfile {0}'.format(zone_export_id)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
|
||||
class ZoneImportCommands(object):
|
||||
"""A mixin for DesignateCLI to add zone import commands"""
|
||||
|
||||
def zone_import_list(self, *args, **kwargs):
|
||||
cmd = 'zone import list'
|
||||
return self.parsed_cmd(cmd, ListModel, *args, **kwargs)
|
||||
|
||||
def zone_import_create(self, zone_file_path, *args, **kwargs):
|
||||
cmd = 'zone import create {0}'.format(zone_file_path)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
def zone_import_show(self, zone_import_id, *args, **kwargs):
|
||||
cmd = 'zone import show {0}'.format(zone_import_id)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
def zone_import_delete(self, zone_import_id, *args, **kwargs):
|
||||
cmd = 'zone import delete {0}'.format(zone_import_id)
|
||||
return self.parsed_cmd(cmd, *args, **kwargs)
|
||||
|
||||
|
||||
class RecordsetCommands(object):
|
||||
|
||||
def recordset_show(self, zone_id, id, *args, **kwargs):
|
||||
cmd = 'recordset show {0} {1}'.format(zone_id, id)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
def recordset_list(self, zone_id, *args, **kwargs):
|
||||
cmd = 'recordset list {0}'.format(zone_id)
|
||||
return self.parsed_cmd(cmd, ListModel, *args, **kwargs)
|
||||
|
||||
def recordset_create(self, zone_id, name, records=None, type=None,
|
||||
description=None, ttl=None, *args, **kwargs):
|
||||
options_str = build_option_string({
|
||||
'--records': records,
|
||||
'--type': type,
|
||||
'--description': description,
|
||||
'--ttl': ttl,
|
||||
})
|
||||
cmd = 'recordset create {0} {1} {2}'.format(zone_id, name, options_str)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
def recordset_set(self, zone_id, id, records=None, type=None,
|
||||
description=None, ttl=None, no_description=False,
|
||||
no_ttl=False, *args, **kwargs):
|
||||
options_str = build_option_string({
|
||||
'--records': records,
|
||||
'--type': type,
|
||||
'--description': description,
|
||||
'--ttl': ttl,
|
||||
})
|
||||
flags_str = build_flags_string({
|
||||
'--no-description': no_description,
|
||||
'--no-ttl': no_ttl,
|
||||
})
|
||||
cmd = 'recordset set {0} {1} {2} {3}'.format(
|
||||
zone_id, id, flags_str, options_str)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
def recordset_delete(self, zone_id, id, *args, **kwargs):
|
||||
cmd = 'recordset delete {0} {1}'.format(zone_id, id)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
|
||||
class TLDCommands(object):
|
||||
|
||||
def tld_list(self, *args, **kwargs):
|
||||
return self.parsed_cmd('tld list', ListModel, *args, **kwargs)
|
||||
|
||||
def tld_show(self, id, *args, **kwargs):
|
||||
return self.parsed_cmd('tld show {0}'.format(id), FieldValueModel,
|
||||
*args, **kwargs)
|
||||
|
||||
def tld_delete(self, id, *args, **kwargs):
|
||||
return self.parsed_cmd('tld delete {0}'.format(id), *args, **kwargs)
|
||||
|
||||
def tld_create(self, name, description=None, *args, **kwargs):
|
||||
options_str = build_option_string({
|
||||
'--name': name,
|
||||
'--description': description,
|
||||
})
|
||||
cmd = 'tld create {0}'.format(options_str)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
def tld_set(self, id, name=None, description=None, no_description=False,
|
||||
*args, **kwargs):
|
||||
options_str = build_option_string({
|
||||
'--name': name,
|
||||
'--description': description,
|
||||
})
|
||||
flags_str = build_flags_string({'--no-description': no_description})
|
||||
cmd = 'tld set {0} {1} {2}'.format(id, options_str, flags_str)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
|
||||
class BlacklistCommands(object):
|
||||
|
||||
def zone_blacklist_list(self, *args, **kwargs):
|
||||
cmd = 'zone blacklist list'
|
||||
return self.parsed_cmd(cmd, ListModel, *args, **kwargs)
|
||||
|
||||
def zone_blacklist_create(self, pattern, description=None, *args,
|
||||
**kwargs):
|
||||
options_str = build_option_string({
|
||||
'--pattern': pattern,
|
||||
'--description': description,
|
||||
})
|
||||
cmd = 'zone blacklist create {0}'.format(options_str)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
def zone_blacklist_set(self, id, pattern=None, description=None,
|
||||
no_description=False, *args, **kwargs):
|
||||
options_str = build_option_string({
|
||||
'--pattern': pattern,
|
||||
'--description': description,
|
||||
})
|
||||
flags_str = build_flags_string({'--no-description': no_description})
|
||||
cmd = 'zone blacklist set {0} {1} {2}'.format(id, options_str,
|
||||
flags_str)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
def zone_blacklist_show(self, id, *args, **kwargs):
|
||||
cmd = 'zone blacklist show {0}'.format(id)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
def zone_blacklist_delete(self, id, *args, **kwargs):
|
||||
cmd = 'zone blacklist delete {0}'.format(id)
|
||||
return self.parsed_cmd(cmd, FieldValueModel, *args, **kwargs)
|
||||
|
||||
|
||||
class DesignateCLI(base.CLIClient, ZoneCommands, ZoneTransferCommands,
|
||||
ZoneExportCommands, ZoneImportCommands, RecordsetCommands,
|
||||
TLDCommands, BlacklistCommands):
|
||||
|
||||
# instantiate this once to minimize requests to keystone
|
||||
_CLIENTS = None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DesignateCLI, self).__init__(*args, **kwargs)
|
||||
# grab the project id. this is used for zone transfer requests
|
||||
resp = FieldValueModel(self.openstack('token issue'))
|
||||
self.project_id = resp.project_id
|
||||
|
||||
@property
|
||||
def using_auth_override(self):
|
||||
return bool(cfg.CONF.identity.override_endpoint)
|
||||
|
||||
@classmethod
|
||||
def get_clients(cls):
|
||||
if not cls._CLIENTS:
|
||||
cls._init_clients()
|
||||
return cls._CLIENTS
|
||||
|
||||
@classmethod
|
||||
def _init_clients(cls):
|
||||
cls._CLIENTS = {
|
||||
'default': DesignateCLI(
|
||||
cli_dir=cfg.CONF.designateclient.directory,
|
||||
username=cfg.CONF.identity.username,
|
||||
password=cfg.CONF.identity.password,
|
||||
tenant_name=cfg.CONF.identity.tenant_name,
|
||||
uri=cfg.CONF.identity.uri,
|
||||
),
|
||||
'alt': DesignateCLI(
|
||||
cli_dir=cfg.CONF.designateclient.directory,
|
||||
username=cfg.CONF.identity.alt_username,
|
||||
password=cfg.CONF.identity.alt_password,
|
||||
tenant_name=cfg.CONF.identity.alt_tenant_name,
|
||||
uri=cfg.CONF.identity.uri,
|
||||
),
|
||||
'admin': DesignateCLI(
|
||||
cli_dir=cfg.CONF.designateclient.directory,
|
||||
username=cfg.CONF.identity.admin_username,
|
||||
password=cfg.CONF.identity.admin_password,
|
||||
tenant_name=cfg.CONF.identity.admin_tenant_name,
|
||||
uri=cfg.CONF.identity.uri,
|
||||
)
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def as_user(self, user):
|
||||
clients = self.get_clients()
|
||||
if user in clients:
|
||||
return clients[user]
|
||||
raise Exception("User '{0}' does not exist".format(user))
|
||||
|
||||
def parsed_cmd(self, cmd, model=None, *args, **kwargs):
|
||||
if self.using_auth_override:
|
||||
# use --os-url and --os-token
|
||||
func = self._openstack_noauth
|
||||
else:
|
||||
# use --os-username --os-tenant-name --os-password --os-auth-url
|
||||
func = self.openstack
|
||||
|
||||
out = func(cmd, *args, **kwargs)
|
||||
LOG.debug(out)
|
||||
if model is not None:
|
||||
return model(out)
|
||||
return out
|
||||
|
||||
def _openstack_noauth(self, cmd, *args, **kwargs):
|
||||
exe = os.path.join(cfg.CONF.designateclient.directory, 'openstack')
|
||||
options = build_option_string({
|
||||
'--os-url': cfg.CONF.identity.override_endpoint,
|
||||
'--os-token': cfg.CONF.identity.override_token,
|
||||
})
|
||||
cmd = options + " " + cmd
|
||||
return base.execute(exe, cmd, *args, **kwargs)
|
@@ -1,69 +0,0 @@
|
||||
"""
|
||||
Copyright 2015 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 os
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
cfg.CONF.register_group(cfg.OptGroup(
|
||||
name='identity', title="Configuration for Keystone auth"
|
||||
))
|
||||
|
||||
cfg.CONF.register_group(cfg.OptGroup(
|
||||
name='designateclient', title="Configuration for the Designate client"
|
||||
))
|
||||
|
||||
cfg.CONF.register_opts([
|
||||
cfg.StrOpt('uri', help="The Keystone v2 endpoint"),
|
||||
cfg.StrOpt('uri_v3', help="The Keystone v3 endpoint"),
|
||||
cfg.StrOpt('auth_version', default='v2'),
|
||||
cfg.StrOpt('region', default='RegionOne'),
|
||||
|
||||
cfg.StrOpt('username'),
|
||||
cfg.StrOpt('tenant_name'),
|
||||
cfg.StrOpt('password', secret=True),
|
||||
cfg.StrOpt('domain_name'),
|
||||
|
||||
cfg.StrOpt('alt_username'),
|
||||
cfg.StrOpt('alt_tenant_name'),
|
||||
cfg.StrOpt('alt_password', secret=True),
|
||||
cfg.StrOpt('alt_domain_name'),
|
||||
|
||||
cfg.StrOpt('admin_username'),
|
||||
cfg.StrOpt('admin_tenant_name'),
|
||||
cfg.StrOpt('admin_password', secret=True),
|
||||
cfg.StrOpt('admin_domain_name'),
|
||||
|
||||
cfg.StrOpt("override_endpoint",
|
||||
help="use this url instead of the url in the service catalog"),
|
||||
cfg.StrOpt("override_token",
|
||||
help="with the override endpoint, pass this token to the api"),
|
||||
], group='identity')
|
||||
|
||||
|
||||
cfg.CONF.register_opts([
|
||||
cfg.StrOpt('directory',
|
||||
help='the directory containing the client executable'),
|
||||
], group='designateclient')
|
||||
|
||||
|
||||
def find_config_file():
|
||||
return os.environ.get(
|
||||
'TEMPEST_CONFIG', '/opt/stack/tempest/etc/tempest.conf')
|
||||
|
||||
|
||||
def read_config():
|
||||
cfg.CONF(args=[], default_config_files=[find_config_file()])
|
@@ -1,48 +0,0 @@
|
||||
"""
|
||||
Copyright 2015 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 random
|
||||
import string
|
||||
|
||||
|
||||
def random_digits(n=8):
|
||||
return "".join([random.choice(string.digits) for _ in range(n)])
|
||||
|
||||
|
||||
def random_tld(name='testtld'):
|
||||
return "{0}{1}".format(name, random_digits())
|
||||
|
||||
|
||||
def random_zone_name(name='testdomain', tld='com'):
|
||||
return "{0}{1}.{2}.".format(name, random_digits(), tld)
|
||||
|
||||
|
||||
def random_a_recordset_name(zone_name, recordset_name='testrecord'):
|
||||
return "{0}{1}.{2}".format(recordset_name, random_digits(), zone_name)
|
||||
|
||||
|
||||
def random_blacklist(name='testblacklist'):
|
||||
return '{0}{1}'.format(name, random_digits())
|
||||
|
||||
|
||||
def random_zone_file(name='testzoneimport'):
|
||||
return "$ORIGIN {0}{1}.com.\n" \
|
||||
"$TTL 300\n" \
|
||||
"{0}{1}.com. 300 IN SOA ns.{0}{1}.com. " \
|
||||
"nsadmin.{0}{1}.com. 42 42 42 42 42\n" \
|
||||
"{0}{1}.com. 300 IN NS ns.{0}{1}.com.\n" \
|
||||
"{0}{1}.com. 300 IN MX 10 mail.{0}{1}.com.\n" \
|
||||
"ns.{0}{1}.com. 300 IN A 10.0.0.1\n" \
|
||||
"mail.{0}{1}.com. 300 IN A 10.0.0.2\n".format(name, random_digits())
|
@@ -1,96 +0,0 @@
|
||||
"""
|
||||
Copyright 2015 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 six
|
||||
from tempest.lib.cli import output_parser
|
||||
|
||||
|
||||
class Model(object):
|
||||
|
||||
def __str__(self):
|
||||
return str(self.__dict__)
|
||||
|
||||
|
||||
class FieldValueModel(Model):
|
||||
"""This converts cli output from messy lists/dicts to neat attributes."""
|
||||
|
||||
def __init__(self, out):
|
||||
"""This parses output with fields and values like:
|
||||
|
||||
+----------------+------------------------------+
|
||||
| Field | Value |
|
||||
+----------------+------------------------------+
|
||||
| action | CREATE |
|
||||
| created_at | 2015-08-20T17:22:17.000000 |
|
||||
| description | None |
|
||||
+----------------+------------------------------+
|
||||
|
||||
These are then accessible as:
|
||||
|
||||
model.action
|
||||
model.created_at
|
||||
model.description
|
||||
|
||||
"""
|
||||
table = output_parser.table(out)
|
||||
|
||||
# Because the output_parser handles Values with multiple lines
|
||||
# in additional Field/Value pairs with Field name '', the following
|
||||
# code is necessary to aggregate Values.
|
||||
#
|
||||
# The list of Field/Value pairs is in-order, so we can append Value
|
||||
# continuation to the previously seen Field, with a newline separator.
|
||||
value_lines = []
|
||||
prev_field = None
|
||||
for field, value in table['values']:
|
||||
if field == '':
|
||||
value_lines.append(value)
|
||||
setattr(self, prev_field, '\n'.join(value_lines))
|
||||
else:
|
||||
setattr(self, field, value)
|
||||
prev_field = field
|
||||
value_lines = [value]
|
||||
|
||||
|
||||
class ListEntryModel(Model):
|
||||
|
||||
def __init__(self, fields, values):
|
||||
for k, v in six.moves.zip(fields, values):
|
||||
setattr(self, k, v)
|
||||
|
||||
|
||||
class ListModel(Model, list):
|
||||
|
||||
def __init__(self, out):
|
||||
"""This parses an output table with any number of headers, and any
|
||||
number of entries:
|
||||
|
||||
+--------------------------------------+----------+---------+
|
||||
| id | name | type |
|
||||
+--------------------------------------+----------+---------+
|
||||
| e658a875-1024-4f88-a347-e5b244ec5a10 | aaa.com. | PRIMARY |
|
||||
+--------------------------------------+----------+---------+
|
||||
| 98d1fb5f-2954-448e-988e-6f1df0f24c52 | bbb.com. | PRIMARY |
|
||||
+--------------------------------------+----------+---------+
|
||||
|
||||
These are then accessible as:
|
||||
|
||||
model[0].name == 'aaa.com.'
|
||||
model[1].name == 'bbb.com.'
|
||||
|
||||
"""
|
||||
table = output_parser.table(out)
|
||||
for entry in table['values']:
|
||||
self.append(ListEntryModel(table['headers'], entry))
|
@@ -1,213 +0,0 @@
|
||||
"""
|
||||
Copyright 2015 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 __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
import tempfile
|
||||
import traceback
|
||||
|
||||
import fixtures
|
||||
from tempest.lib.exceptions import CommandFailed
|
||||
from testtools.runtest import MultipleExceptions
|
||||
|
||||
from designateclient.functionaltests.client import DesignateCLI
|
||||
|
||||
|
||||
class BaseFixture(fixtures.Fixture):
|
||||
|
||||
def __init__(self, user='default', *args, **kwargs):
|
||||
"""args/kwargs are forwarded to a create method on DesignateCLI"""
|
||||
super(BaseFixture, self).__init__()
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
self.client = DesignateCLI.as_user(user)
|
||||
|
||||
def setUp(self):
|
||||
# Sometimes, exceptions are raised in _setUp methods on fixtures.
|
||||
# testtools pushes the exception into a MultipleExceptions object along
|
||||
# with an artificial SetupError, which produces bad error messages.
|
||||
# This just logs those stack traces to stderr for easier debugging.
|
||||
try:
|
||||
super(BaseFixture, self).setUp()
|
||||
except MultipleExceptions as e:
|
||||
for i, exc_info in enumerate(e.args):
|
||||
print('--- printing MultipleExceptions traceback {} of {} ---'
|
||||
.format(i + 1, len(e.args)), file=sys.stderr)
|
||||
traceback.print_exception(*exc_info)
|
||||
raise
|
||||
|
||||
|
||||
class ZoneFixture(BaseFixture):
|
||||
"""See DesignateCLI.zone_create for __init__ args"""
|
||||
|
||||
def _setUp(self):
|
||||
super(ZoneFixture, self)._setUp()
|
||||
self.zone = self.client.zone_create(*self.args, **self.kwargs)
|
||||
self.addCleanup(self.cleanup_zone, self.client, self.zone.id)
|
||||
|
||||
@classmethod
|
||||
def cleanup_zone(cls, client, zone_id):
|
||||
try:
|
||||
client.zone_delete(zone_id)
|
||||
except CommandFailed:
|
||||
pass
|
||||
|
||||
|
||||
class TransferRequestFixture(BaseFixture):
|
||||
"""See DesignateCLI.zone_transfer_request_create for __init__ args"""
|
||||
|
||||
def __init__(self, zone, user='default', target_user='alt', *args,
|
||||
**kwargs):
|
||||
super(TransferRequestFixture, self).__init__(user, *args, **kwargs)
|
||||
self.zone = zone
|
||||
self.target_client = DesignateCLI.as_user(target_user)
|
||||
|
||||
# the client has a bug such that it requires --target-project-id.
|
||||
# when this bug is fixed, please remove this
|
||||
self.kwargs['target_project_id'] = self.target_client.project_id
|
||||
|
||||
def _setUp(self):
|
||||
super(TransferRequestFixture, self)._setUp()
|
||||
self.transfer_request = self.client.zone_transfer_request_create(
|
||||
zone_id=self.zone.id,
|
||||
*self.args, **self.kwargs
|
||||
)
|
||||
self.addCleanup(self.cleanup_transfer_request, self.client,
|
||||
self.transfer_request.id)
|
||||
self.addCleanup(ZoneFixture.cleanup_zone, self.client, self.zone.id)
|
||||
self.addCleanup(ZoneFixture.cleanup_zone, self.target_client,
|
||||
self.zone.id)
|
||||
|
||||
@classmethod
|
||||
def cleanup_transfer_request(cls, client, transfer_request_id):
|
||||
try:
|
||||
client.zone_transfer_request_delete(transfer_request_id)
|
||||
except CommandFailed:
|
||||
pass
|
||||
|
||||
|
||||
class ExportFixture(BaseFixture):
|
||||
"""See DesignateCLI.zone_export_create for __init__ args"""
|
||||
|
||||
def __init__(self, zone, user='default', *args, **kwargs):
|
||||
super(ExportFixture, self).__init__(user, *args, **kwargs)
|
||||
self.zone = zone
|
||||
|
||||
def _setUp(self):
|
||||
super(ExportFixture, self)._setUp()
|
||||
self.zone_export = self.client.zone_export_create(
|
||||
zone_id=self.zone.id,
|
||||
*self.args, **self.kwargs
|
||||
)
|
||||
self.addCleanup(self.cleanup_zone_export, self.client,
|
||||
self.zone_export.id)
|
||||
self.addCleanup(ZoneFixture.cleanup_zone, self.client, self.zone.id)
|
||||
|
||||
@classmethod
|
||||
def cleanup_zone_export(cls, client, zone_export_id):
|
||||
try:
|
||||
client.zone_export_delete(zone_export_id)
|
||||
except CommandFailed:
|
||||
pass
|
||||
|
||||
|
||||
class ImportFixture(BaseFixture):
|
||||
"""See DesignateCLI.zone_import_create for __init__ args"""
|
||||
|
||||
def __init__(self, zone_file_contents, user='default', *args, **kwargs):
|
||||
super(ImportFixture, self).__init__(user, *args, **kwargs)
|
||||
self.zone_file_contents = zone_file_contents
|
||||
|
||||
def _setUp(self):
|
||||
super(ImportFixture, self)._setUp()
|
||||
|
||||
with tempfile.NamedTemporaryFile() as f:
|
||||
f.write(self.zone_file_contents)
|
||||
f.flush()
|
||||
|
||||
self.zone_import = self.client.zone_import_create(
|
||||
zone_file_path=f.name,
|
||||
*self.args, **self.kwargs
|
||||
)
|
||||
|
||||
self.addCleanup(self.cleanup_zone_import, self.client,
|
||||
self.zone_import.id)
|
||||
self.addCleanup(ZoneFixture.cleanup_zone, self.client,
|
||||
self.zone_import.zone_id)
|
||||
|
||||
@classmethod
|
||||
def cleanup_zone_import(cls, client, zone_import_id):
|
||||
try:
|
||||
client.zone_import_delete(zone_import_id)
|
||||
except CommandFailed:
|
||||
pass
|
||||
|
||||
|
||||
class RecordsetFixture(BaseFixture):
|
||||
"""See DesignateCLI.recordset_create for __init__ args"""
|
||||
|
||||
def _setUp(self):
|
||||
super(RecordsetFixture, self)._setUp()
|
||||
self.recordset = self.client.recordset_create(
|
||||
*self.args, **self.kwargs)
|
||||
self.addCleanup(self.cleanup_recordset, self.client,
|
||||
self.recordset.zone_id, self.recordset.id)
|
||||
|
||||
@classmethod
|
||||
def cleanup_recordset(cls, client, zone_id, recordset_id):
|
||||
try:
|
||||
client.recordset_delete(zone_id, recordset_id)
|
||||
except CommandFailed:
|
||||
pass
|
||||
|
||||
|
||||
class TLDFixture(BaseFixture):
|
||||
"""See DesignateCLI.tld_create for __init__ args"""
|
||||
|
||||
def __init__(self, user='admin', *args, **kwargs):
|
||||
super(TLDFixture, self).__init__(user=user, *args, **kwargs)
|
||||
|
||||
def _setUp(self):
|
||||
super(TLDFixture, self)._setUp()
|
||||
self.tld = self.client.tld_create(*self.args, **self.kwargs)
|
||||
self.addCleanup(self.cleanup_tld, self.client, self.tld.id)
|
||||
|
||||
@classmethod
|
||||
def cleanup_tld(cls, client, tld_id):
|
||||
try:
|
||||
client.tld_delete(tld_id)
|
||||
except CommandFailed:
|
||||
pass
|
||||
|
||||
|
||||
class BlacklistFixture(BaseFixture):
|
||||
"""See DesignateCLI.zone_blacklist_create for __init__ args"""
|
||||
|
||||
def __init__(self, user='admin', *args, **kwargs):
|
||||
super(BlacklistFixture, self).__init__(user=user, *args, **kwargs)
|
||||
|
||||
def _setUp(self):
|
||||
super(BlacklistFixture, self)._setUp()
|
||||
self.blacklist = self.client.zone_blacklist_create(*self.args,
|
||||
**self.kwargs)
|
||||
self.addCleanup(self.cleanup_blacklist, self.client, self.blacklist.id)
|
||||
|
||||
@classmethod
|
||||
def cleanup_blacklist(cls, client, blacklist_id):
|
||||
try:
|
||||
client.zone_blacklist_delete(blacklist_id)
|
||||
except CommandFailed:
|
||||
pass
|
@@ -1,98 +0,0 @@
|
||||
"""
|
||||
Copyright 2015 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 tempest.lib.exceptions import CommandFailed
|
||||
|
||||
from designateclient.functionaltests.base import BaseDesignateTest
|
||||
from designateclient.functionaltests.datagen import random_blacklist
|
||||
from designateclient.functionaltests.v2.fixtures import BlacklistFixture
|
||||
|
||||
|
||||
class TestBlacklist(BaseDesignateTest):
|
||||
|
||||
def setUp(self):
|
||||
super(TestBlacklist, self).setUp()
|
||||
pattern = random_blacklist()
|
||||
self.blacklist = self.useFixture(BlacklistFixture(
|
||||
pattern=pattern,
|
||||
description='A random blacklist',
|
||||
)).blacklist
|
||||
|
||||
self.assertEqual(self.blacklist.pattern, pattern)
|
||||
self.assertEqual(self.blacklist.description, 'A random blacklist')
|
||||
|
||||
def test_zone_blacklist_list(self):
|
||||
blacklists = self.clients.as_user('admin').zone_blacklist_list()
|
||||
self.assertGreater(len(blacklists), 0)
|
||||
|
||||
def test_zone_blacklist_create_and_show(self):
|
||||
client = self.clients.as_user('admin')
|
||||
blacklist = client.zone_blacklist_show(self.blacklist.id)
|
||||
|
||||
self.assertEqual(self.blacklist.created_at, blacklist.created_at)
|
||||
self.assertEqual(self.blacklist.description, blacklist.description)
|
||||
self.assertEqual(self.blacklist.id, blacklist.id)
|
||||
self.assertEqual(self.blacklist.pattern, blacklist.pattern)
|
||||
self.assertEqual(self.blacklist.updated_at, blacklist.updated_at)
|
||||
|
||||
def test_zone_blacklist_delete(self):
|
||||
client = self.clients.as_user('admin')
|
||||
client.zone_blacklist_delete(self.blacklist.id)
|
||||
self.assertRaises(CommandFailed, client.zone_blacklist_show,
|
||||
self.blacklist.id)
|
||||
|
||||
def test_zone_blacklist_set(self):
|
||||
client = self.clients.as_user('admin')
|
||||
updated_pattern = random_blacklist('updatedblacklist')
|
||||
blacklist = client.zone_blacklist_set(
|
||||
id=self.blacklist.id,
|
||||
pattern=updated_pattern,
|
||||
description='An updated blacklist',
|
||||
)
|
||||
|
||||
self.assertEqual(blacklist.created_at, self.blacklist.created_at)
|
||||
self.assertEqual(blacklist.description, 'An updated blacklist')
|
||||
self.assertEqual(blacklist.id, self.blacklist.id)
|
||||
self.assertEqual(blacklist.pattern, updated_pattern)
|
||||
self.assertNotEqual(blacklist.updated_at, self.blacklist.updated_at)
|
||||
|
||||
def test_zone_blacklist_set_no_description(self):
|
||||
client = self.clients.as_user('admin')
|
||||
blacklist = client.zone_blacklist_set(
|
||||
id=self.blacklist.id,
|
||||
no_description=True,
|
||||
)
|
||||
self.assertEqual(blacklist.description, 'None')
|
||||
|
||||
def test_cannot_set_description_with_no_description_flag(self):
|
||||
client = self.clients.as_user('admin')
|
||||
self.assertRaises(CommandFailed, client.zone_blacklist_set,
|
||||
self.blacklist.id,
|
||||
pattern=random_blacklist(),
|
||||
description='new description',
|
||||
no_description=True)
|
||||
|
||||
|
||||
class TestBlacklistNegative(BaseDesignateTest):
|
||||
|
||||
def test_invalid_blacklist_command(self):
|
||||
client = self.clients.as_user('admin')
|
||||
cmd = 'zone blacklist notacommand'
|
||||
self.assertRaises(CommandFailed, client.openstack, cmd)
|
||||
|
||||
def test_blacklist_create_invalid_flag(self):
|
||||
client = self.clients.as_user('admin')
|
||||
cmd = 'zone blacklist create --pattern helloworld --notaflag invalid'
|
||||
self.assertRaises(CommandFailed, client.openstack, cmd)
|
@@ -1,111 +0,0 @@
|
||||
"""
|
||||
Copyright 2015 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 tempest.lib.exceptions import CommandFailed
|
||||
|
||||
from designateclient.functionaltests.base import BaseDesignateTest
|
||||
from designateclient.functionaltests.datagen import random_a_recordset_name
|
||||
from designateclient.functionaltests.datagen import random_zone_name
|
||||
from designateclient.functionaltests.v2.fixtures import RecordsetFixture
|
||||
from designateclient.functionaltests.v2.fixtures import ZoneFixture
|
||||
|
||||
|
||||
class TestRecordset(BaseDesignateTest):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRecordset, self).setUp()
|
||||
self.ensure_tld_exists('com')
|
||||
self.zone = self.useFixture(ZoneFixture(
|
||||
name=random_zone_name(),
|
||||
email='test@example.com',
|
||||
)).zone
|
||||
|
||||
name = random_a_recordset_name(self.zone.name)
|
||||
self.recordset = self.useFixture(RecordsetFixture(
|
||||
zone_id=self.zone.id,
|
||||
name=name,
|
||||
records='1.2.3.4',
|
||||
description='An a recordset',
|
||||
type='A',
|
||||
ttl=1234,
|
||||
)).recordset
|
||||
|
||||
self.assertEqual(self.recordset.name, name)
|
||||
self.assertEqual(self.recordset.records, '1.2.3.4')
|
||||
self.assertEqual(self.recordset.description, 'An a recordset')
|
||||
self.assertEqual(self.recordset.type, 'A')
|
||||
self.assertEqual(self.recordset.ttl, '1234')
|
||||
|
||||
def test_recordset_list(self):
|
||||
rsets = self.clients.recordset_list(self.zone.id)
|
||||
self.assertGreater(len(rsets), 0)
|
||||
|
||||
def test_recordset_create_and_show(self):
|
||||
rset = self.clients.recordset_show(self.zone.id, self.recordset.id)
|
||||
self.assertTrue(hasattr(self.recordset, 'action'))
|
||||
self.assertTrue(hasattr(rset, 'action'))
|
||||
self.assertEqual(self.recordset.created_at, rset.created_at)
|
||||
self.assertEqual(self.recordset.description, rset.description)
|
||||
self.assertEqual(self.recordset.id, rset.id)
|
||||
self.assertEqual(self.recordset.name, rset.name)
|
||||
self.assertEqual(self.recordset.records, rset.records)
|
||||
self.assertEqual(self.recordset.status, rset.status)
|
||||
self.assertEqual(self.recordset.ttl, rset.ttl)
|
||||
self.assertEqual(self.recordset.type, rset.type)
|
||||
self.assertEqual(self.recordset.updated_at, rset.updated_at)
|
||||
self.assertEqual(self.recordset.version, rset.version)
|
||||
self.assertEqual(self.recordset.zone_id, self.zone.id)
|
||||
|
||||
def test_recordset_delete(self):
|
||||
rset = self.clients.recordset_delete(self.zone.id, self.recordset.id)
|
||||
self.assertEqual(rset.action, 'DELETE')
|
||||
self.assertEqual(rset.status, 'PENDING')
|
||||
|
||||
def test_recordset_set(self):
|
||||
rset = self.clients.recordset_set(
|
||||
self.zone.id,
|
||||
self.recordset.id,
|
||||
records='2.3.4.5',
|
||||
ttl=2345,
|
||||
description='Updated description',
|
||||
)
|
||||
|
||||
self.assertEqual(rset.records, '2.3.4.5')
|
||||
self.assertEqual(rset.ttl, '2345')
|
||||
self.assertEqual(rset.description, 'Updated description')
|
||||
|
||||
def test_recordset_set_clear_ttl_and_description(self):
|
||||
rset = self.clients.recordset_set(
|
||||
self.zone.id,
|
||||
self.recordset.id,
|
||||
no_description=True,
|
||||
no_ttl=True,
|
||||
)
|
||||
|
||||
self.assertEqual(rset.description, 'None')
|
||||
self.assertEqual(rset.ttl, 'None')
|
||||
|
||||
|
||||
class TestRecordsetNegative(BaseDesignateTest):
|
||||
|
||||
def test_invalid_option_on_recordset_create(self):
|
||||
cmd = 'recordset create de47d30b-41c5-4e38-b2c5-e0b908e19ec7 ' \
|
||||
'aaa.desig.com. --type A --records 1.2.3.4 ' \
|
||||
'--invalid "not valid"'
|
||||
self.assertRaises(CommandFailed, self.clients.openstack, cmd)
|
||||
|
||||
def test_invalid_recordset_command(self):
|
||||
cmd = 'recordset hopefullynotvalid'
|
||||
self.assertRaises(CommandFailed, self.clients.openstack, cmd)
|
@@ -1,82 +0,0 @@
|
||||
"""
|
||||
Copyright 2015 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 tempest.lib.exceptions import CommandFailed
|
||||
|
||||
from designateclient.functionaltests.base import BaseDesignateTest
|
||||
from designateclient.functionaltests.datagen import random_tld
|
||||
from designateclient.functionaltests.v2.fixtures import TLDFixture
|
||||
|
||||
|
||||
class TestTld(BaseDesignateTest):
|
||||
|
||||
def setUp(self):
|
||||
super(TestTld, self).setUp()
|
||||
tld_name = random_tld()
|
||||
self.tld = self.useFixture(TLDFixture(
|
||||
name=tld_name,
|
||||
description='A random tld',
|
||||
)).tld
|
||||
|
||||
self.assertEqual(self.tld.name, tld_name)
|
||||
self.assertEqual(self.tld.description, 'A random tld')
|
||||
|
||||
def test_tld_list(self):
|
||||
tlds = self.clients.as_user('admin').tld_list()
|
||||
self.assertGreater(len(tlds), 0)
|
||||
|
||||
def test_tld_create_and_show(self):
|
||||
tld = self.clients.as_user('admin').tld_show(self.tld.id)
|
||||
self.assertEqual(tld.name, self.tld.name)
|
||||
self.assertEqual(tld.created_at, self.tld.created_at)
|
||||
self.assertEqual(tld.id, self.tld.id)
|
||||
self.assertEqual(tld.name, self.tld.name)
|
||||
self.assertEqual(tld.updated_at, self.tld.updated_at)
|
||||
|
||||
def test_tld_delete(self):
|
||||
client = self.clients.as_user('admin')
|
||||
client.tld_delete(self.tld.id)
|
||||
self.assertRaises(CommandFailed, client.tld_show, self.tld.id)
|
||||
|
||||
def test_tld_set(self):
|
||||
client = self.clients.as_user('admin')
|
||||
updated_name = random_tld('updated')
|
||||
tld = client.tld_set(self.tld.id, name=updated_name,
|
||||
description='An updated tld')
|
||||
self.assertEqual(tld.description, 'An updated tld')
|
||||
self.assertEqual(tld.name, updated_name)
|
||||
|
||||
def test_tld_set_no_description(self):
|
||||
client = self.clients.as_user('admin')
|
||||
tld = client.tld_set(self.tld.id, no_description=True)
|
||||
self.assertEqual(tld.description, 'None')
|
||||
|
||||
def test_no_set_tld_with_description_and_no_description(self):
|
||||
client = self.clients.as_user('admin')
|
||||
self.assertRaises(CommandFailed, client.tld_set, self.tld.id,
|
||||
description='An updated tld',
|
||||
no_description=True)
|
||||
|
||||
|
||||
class TestTldNegative(BaseDesignateTest):
|
||||
|
||||
def test_tld_invalid_commmand(self):
|
||||
client = self.clients.as_user('admin')
|
||||
self.assertRaises(CommandFailed, client.openstack, 'tld notacommand')
|
||||
|
||||
def test_tld_create_invalid_flag(self):
|
||||
client = self.clients.as_user('admin')
|
||||
self.assertRaises(CommandFailed, client.openstack,
|
||||
'tld create --notanoption "junk"')
|
@@ -1,130 +0,0 @@
|
||||
"""
|
||||
Copyright 2015 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 tempest.lib.exceptions import CommandFailed
|
||||
|
||||
from designateclient.functionaltests.base import BaseDesignateTest
|
||||
from designateclient.functionaltests.datagen import random_zone_name
|
||||
from designateclient.functionaltests.v2.fixtures import ZoneFixture
|
||||
|
||||
|
||||
class TestZone(BaseDesignateTest):
|
||||
|
||||
def setUp(self):
|
||||
super(TestZone, self).setUp()
|
||||
self.ensure_tld_exists('com')
|
||||
self.fixture = self.useFixture(ZoneFixture(
|
||||
name=random_zone_name(),
|
||||
email='test@example.com',
|
||||
))
|
||||
self.zone = self.fixture.zone
|
||||
|
||||
def test_zone_list(self):
|
||||
zones = self.clients.zone_list()
|
||||
self.assertGreater(len(zones), 0)
|
||||
|
||||
def test_zone_create_and_show(self):
|
||||
zone = self.clients.zone_show(self.zone.id)
|
||||
self.assertTrue(hasattr(zone, 'action'))
|
||||
self.assertEqual(self.zone.created_at, zone.created_at)
|
||||
self.assertEqual(self.zone.description, zone.description)
|
||||
self.assertEqual(self.zone.email, zone.email)
|
||||
self.assertEqual(self.zone.id, zone.id)
|
||||
self.assertEqual(self.zone.masters, zone.masters)
|
||||
self.assertEqual(self.zone.name, zone.name)
|
||||
self.assertEqual(self.zone.pool_id, zone.pool_id)
|
||||
self.assertEqual(self.zone.project_id, zone.project_id)
|
||||
self.assertEqual(self.zone.serial, zone.serial)
|
||||
self.assertTrue(hasattr(zone, 'status'))
|
||||
self.assertEqual(self.zone.transferred_at, zone.transferred_at)
|
||||
self.assertEqual(self.zone.ttl, zone.ttl)
|
||||
self.assertEqual(self.zone.type, zone.type)
|
||||
self.assertEqual(self.zone.updated_at, zone.updated_at)
|
||||
self.assertEqual(self.zone.version, zone.version)
|
||||
|
||||
def test_zone_delete(self):
|
||||
zone = self.clients.zone_delete(self.zone.id)
|
||||
self.assertEqual(zone.action, 'DELETE')
|
||||
self.assertEqual(zone.status, 'PENDING')
|
||||
|
||||
def test_zone_set(self):
|
||||
ttl = int(self.zone.ttl) + 123
|
||||
email = 'updated{0}'.format(self.zone.email)
|
||||
description = 'new description'
|
||||
|
||||
zone = self.clients.zone_set(self.zone.id, ttl=ttl, email=email,
|
||||
description=description)
|
||||
self.assertEqual(ttl, int(zone.ttl))
|
||||
self.assertEqual(email, zone.email)
|
||||
self.assertEqual(description, zone.description)
|
||||
|
||||
def test_invalid_option_on_zone_create(self):
|
||||
cmd = 'zone create %s --invalid "not a valid option"'.format(
|
||||
random_zone_name())
|
||||
self.assertRaises(CommandFailed, self.clients.openstack, cmd)
|
||||
|
||||
def test_invalid_zone_command(self):
|
||||
cmd = 'zone hopefullynotacommand'
|
||||
self.assertRaises(CommandFailed, self.clients.openstack, cmd)
|
||||
|
||||
|
||||
class TestsPassingZoneFlags(BaseDesignateTest):
|
||||
|
||||
def setUp(self):
|
||||
super(TestsPassingZoneFlags, self).setUp()
|
||||
self.ensure_tld_exists('com')
|
||||
|
||||
def test_zone_create_primary_with_all_args(self):
|
||||
zone_name = random_zone_name()
|
||||
fixture = self.useFixture(ZoneFixture(
|
||||
name=zone_name,
|
||||
email='primary@example.com',
|
||||
description='A primary zone',
|
||||
ttl=2345,
|
||||
type='PRIMARY',
|
||||
))
|
||||
zone = fixture.zone
|
||||
self.assertEqual(zone_name, zone.name)
|
||||
self.assertEqual('primary@example.com', zone.email)
|
||||
self.assertEqual('A primary zone', zone.description)
|
||||
self.assertEqual('2345', zone.ttl)
|
||||
self.assertEqual('PRIMARY', zone.type)
|
||||
|
||||
def test_zone_create_secondary_with_all_args(self):
|
||||
zone_name = random_zone_name()
|
||||
fixture = self.useFixture(ZoneFixture(
|
||||
name=zone_name,
|
||||
description='A secondary zone',
|
||||
type='SECONDARY',
|
||||
masters='127.0.0.1',
|
||||
))
|
||||
zone = fixture.zone
|
||||
self.assertEqual(zone_name, zone.name)
|
||||
self.assertEqual('A secondary zone', zone.description)
|
||||
self.assertEqual('SECONDARY', zone.type)
|
||||
self.assertEqual('127.0.0.1', zone.masters)
|
||||
|
||||
def test_zone_set_secondary_masters(self):
|
||||
fixture = self.useFixture(ZoneFixture(
|
||||
name=random_zone_name(),
|
||||
description='A secondary zone',
|
||||
type='SECONDARY',
|
||||
masters='127.0.0.1',
|
||||
))
|
||||
zone = fixture.zone
|
||||
self.assertEqual('127.0.0.1', zone.masters)
|
||||
|
||||
zone = self.clients.zone_set(zone.id, masters='127.0.0.2')
|
||||
self.assertEqual('127.0.0.2', zone.masters)
|
@@ -1,81 +0,0 @@
|
||||
"""
|
||||
Copyright 2016 Rackspace
|
||||
|
||||
Author: Rahman Syed <rahman.syed@gmail.com>
|
||||
|
||||
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 designateclient.functionaltests.base import BaseDesignateTest
|
||||
from designateclient.functionaltests.datagen import random_zone_name
|
||||
from designateclient.functionaltests.v2.fixtures import ExportFixture
|
||||
from designateclient.functionaltests.v2.fixtures import ZoneFixture
|
||||
|
||||
|
||||
class TestZoneExport(BaseDesignateTest):
|
||||
|
||||
def setUp(self):
|
||||
super(TestZoneExport, self).setUp()
|
||||
self.ensure_tld_exists('com')
|
||||
fixture = self.useFixture(ZoneFixture(
|
||||
name=random_zone_name(),
|
||||
email='test@example.com',
|
||||
))
|
||||
self.zone = fixture.zone
|
||||
|
||||
def test_list_zone_exports(self):
|
||||
zone_export = self.useFixture(ExportFixture(
|
||||
zone=self.zone
|
||||
)).zone_export
|
||||
|
||||
zone_exports = self.clients.zone_export_list()
|
||||
self.assertGreater(len(zone_exports), 0)
|
||||
self.assertTrue(self._is_entity_in_list(zone_export, zone_exports))
|
||||
|
||||
def test_create_and_show_zone_export(self):
|
||||
zone_export = self.useFixture(ExportFixture(
|
||||
zone=self.zone
|
||||
)).zone_export
|
||||
|
||||
fetched_export = self.clients.zone_export_show(zone_export.id)
|
||||
|
||||
self.assertEqual(zone_export.created_at, fetched_export.created_at)
|
||||
self.assertEqual(zone_export.id, fetched_export.id)
|
||||
self.assertEqual(zone_export.message, fetched_export.message)
|
||||
self.assertEqual(zone_export.project_id, fetched_export.project_id)
|
||||
self.assertEqual(zone_export.zone_id, fetched_export.zone_id)
|
||||
|
||||
def test_delete_zone_export(self):
|
||||
zone_export = self.useFixture(ExportFixture(
|
||||
zone=self.zone
|
||||
)).zone_export
|
||||
|
||||
zone_exports = self.clients.zone_export_list()
|
||||
self.assertTrue(self._is_entity_in_list(zone_export, zone_exports))
|
||||
|
||||
self.clients.zone_export_delete(zone_export.id)
|
||||
|
||||
zone_exports = self.clients.zone_export_list()
|
||||
self.assertFalse(self._is_entity_in_list(zone_export, zone_exports))
|
||||
|
||||
def test_show_export_file(self):
|
||||
zone_export = self.useFixture(ExportFixture(
|
||||
zone=self.zone
|
||||
)).zone_export
|
||||
|
||||
fetched_export = self.clients.zone_export_showfile(zone_export.id)
|
||||
|
||||
self.assertIn('$ORIGIN', fetched_export.data)
|
||||
self.assertIn('$TTL', fetched_export.data)
|
||||
self.assertIn('SOA', fetched_export.data)
|
||||
self.assertIn('NS', fetched_export.data)
|
||||
self.assertIn(self.zone.name, fetched_export.data)
|
@@ -1,65 +0,0 @@
|
||||
"""
|
||||
Copyright 2016 Rackspace
|
||||
|
||||
Author: Rahman Syed <rahman.syed@gmail.com>
|
||||
|
||||
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 designateclient.functionaltests.base import BaseDesignateTest
|
||||
from designateclient.functionaltests.datagen import random_zone_file
|
||||
from designateclient.functionaltests.v2.fixtures import ImportFixture
|
||||
|
||||
|
||||
class TestZoneImport(BaseDesignateTest):
|
||||
|
||||
def setUp(self):
|
||||
super(TestZoneImport, self).setUp()
|
||||
self.ensure_tld_exists('com')
|
||||
self.zone_file_contents = random_zone_file()
|
||||
|
||||
def test_list_zone_imports(self):
|
||||
zone_import = self.useFixture(ImportFixture(
|
||||
zone_file_contents=self.zone_file_contents
|
||||
)).zone_import
|
||||
|
||||
zone_imports = self.clients.zone_import_list()
|
||||
self.assertGreater(len(zone_imports), 0)
|
||||
self.assertTrue(self._is_entity_in_list(zone_import, zone_imports))
|
||||
|
||||
def test_create_and_show_zone_import(self):
|
||||
zone_import = self.useFixture(ImportFixture(
|
||||
zone_file_contents=self.zone_file_contents
|
||||
)).zone_import
|
||||
|
||||
fetched_import = self.clients.zone_import_show(zone_import.id)
|
||||
|
||||
self.assertEqual(zone_import.created_at, fetched_import.created_at)
|
||||
self.assertEqual(zone_import.id, fetched_import.id)
|
||||
self.assertEqual(zone_import.project_id, fetched_import.project_id)
|
||||
|
||||
# check both statuses to avoid a race condition, causing test failure.
|
||||
# we don't know when the import completes.
|
||||
self.assertIn(fetched_import.status, ['PENDING', 'COMPLETE'])
|
||||
|
||||
def test_delete_zone_import(self):
|
||||
zone_import = self.useFixture(ImportFixture(
|
||||
zone_file_contents=self.zone_file_contents
|
||||
)).zone_import
|
||||
|
||||
zone_imports = self.clients.zone_import_list()
|
||||
self.assertTrue(self._is_entity_in_list(zone_import, zone_imports))
|
||||
|
||||
self.clients.zone_import_delete(zone_import.id)
|
||||
|
||||
zone_imports = self.clients.zone_import_list()
|
||||
self.assertFalse(self._is_entity_in_list(zone_import, zone_imports))
|
@@ -1,118 +0,0 @@
|
||||
"""
|
||||
Copyright 2015 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 unittest
|
||||
|
||||
from tempest.lib.exceptions import CommandFailed
|
||||
|
||||
from designateclient.functionaltests.base import BaseDesignateTest
|
||||
from designateclient.functionaltests.client import DesignateCLI
|
||||
from designateclient.functionaltests.datagen import random_zone_name
|
||||
from designateclient.functionaltests.v2.fixtures import TransferRequestFixture
|
||||
from designateclient.functionaltests.v2.fixtures import ZoneFixture
|
||||
|
||||
|
||||
class TestZoneTransferRequest(BaseDesignateTest):
|
||||
|
||||
def setUp(self):
|
||||
super(TestZoneTransferRequest, self).setUp()
|
||||
self.ensure_tld_exists('com')
|
||||
fixture = self.useFixture(ZoneFixture(
|
||||
name=random_zone_name(),
|
||||
email='test@example.com',
|
||||
))
|
||||
self.zone = fixture.zone
|
||||
|
||||
def test_list_zone_transfer_request(self):
|
||||
self.useFixture(TransferRequestFixture(self.zone))
|
||||
xfrs = self.clients.zone_transfer_request_list()
|
||||
self.assertGreater(len(xfrs), 0)
|
||||
|
||||
def test_create_and_show_zone_transfer_request(self):
|
||||
transfer_request = self.useFixture(TransferRequestFixture(
|
||||
zone=self.zone,
|
||||
user='default',
|
||||
target_user='alt',
|
||||
)).transfer_request
|
||||
|
||||
fetched_xfr = self.clients.zone_transfer_request_show(
|
||||
transfer_request.id)
|
||||
|
||||
self.assertEqual(fetched_xfr.created_at, transfer_request.created_at)
|
||||
self.assertEqual(fetched_xfr.description, transfer_request.description)
|
||||
self.assertEqual(fetched_xfr.id, transfer_request.id)
|
||||
self.assertEqual(fetched_xfr.key, transfer_request.key)
|
||||
self.assertEqual(fetched_xfr.links, transfer_request.links)
|
||||
self.assertEqual(fetched_xfr.target_project_id,
|
||||
transfer_request.target_project_id)
|
||||
self.assertEqual(fetched_xfr.updated_at, transfer_request.updated_at)
|
||||
self.assertEqual(fetched_xfr.status, transfer_request.status)
|
||||
self.assertEqual(fetched_xfr.zone_id, self.zone.id)
|
||||
self.assertEqual(fetched_xfr.zone_name, self.zone.name)
|
||||
|
||||
def test_delete_zone_transfer_request(self):
|
||||
transfer_request = self.useFixture(TransferRequestFixture(
|
||||
zone=self.zone,
|
||||
user='default',
|
||||
target_user='alt',
|
||||
)).transfer_request
|
||||
|
||||
self.clients.zone_transfer_request_delete(transfer_request.id)
|
||||
self.assertRaises(CommandFailed,
|
||||
self.clients.zone_transfer_request_show,
|
||||
transfer_request.id)
|
||||
|
||||
@unittest.skip("Fails because `zone transfer request set` returns nothing")
|
||||
def test_set_zone_transfer_request(self):
|
||||
transfer_request = self.useFixture(TransferRequestFixture(
|
||||
zone=self.zone,
|
||||
description="old description",
|
||||
)).transfer_request
|
||||
|
||||
self.assertEqual(transfer_request.description, "old description")
|
||||
|
||||
updated_xfr = self.clients.zone_transfer_request_set(
|
||||
transfer_request.id,
|
||||
description="updated description")
|
||||
self.assertEqual(updated_xfr.description, "updated description")
|
||||
|
||||
|
||||
class TestZoneTransferAccept(BaseDesignateTest):
|
||||
|
||||
def setUp(self):
|
||||
super(TestZoneTransferAccept, self).setUp()
|
||||
self.ensure_tld_exists('com')
|
||||
fixture = self.useFixture(ZoneFixture(
|
||||
name=random_zone_name(),
|
||||
email='test@example.com',
|
||||
))
|
||||
self.zone = fixture.zone
|
||||
|
||||
self.target_client = DesignateCLI.as_user('alt')
|
||||
fixture = self.useFixture(TransferRequestFixture(
|
||||
zone=self.zone,
|
||||
user='default',
|
||||
target_user='alt',
|
||||
target_project_id=self.target_client.project_id,
|
||||
))
|
||||
self.transfer_request = fixture.transfer_request
|
||||
|
||||
def test_zone_transfer_accept_request(self):
|
||||
self.target_client.zone_transfer_accept_request(
|
||||
id=self.transfer_request.id,
|
||||
key=self.transfer_request.key,
|
||||
)
|
||||
self.target_client.zone_show(self.zone.id)
|
||||
self.assertRaises(CommandFailed, self.clients.zone_show, self.zone.id)
|
@@ -1,53 +0,0 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""OpenStackClient plugin for DNS service."""
|
||||
|
||||
from osc_lib import utils as oscutils
|
||||
|
||||
from designateclient import shell
|
||||
|
||||
|
||||
DEFAULT_API_VERSION = '2'
|
||||
|
||||
API_NAME = 'dns'
|
||||
API_VERSION_OPTION = 'os_dns_api_version'
|
||||
API_VERSIONS = {
|
||||
'2': 'designateclient.v2.client.Client',
|
||||
}
|
||||
|
||||
|
||||
def make_client(instance):
|
||||
cls = oscutils.get_client_class(
|
||||
API_NAME, instance._api_version[API_NAME],
|
||||
API_VERSIONS)
|
||||
kwargs = oscutils.build_kwargs_dict('endpoint_type', instance._interface)
|
||||
|
||||
return cls(session=instance.session,
|
||||
region_name=instance._region_name, **kwargs)
|
||||
|
||||
|
||||
def build_option_parser(parser):
|
||||
"""Hook to add global options."""
|
||||
parser.add_argument(
|
||||
'--os-dns-api-version',
|
||||
metavar='<dns-api-version>',
|
||||
default=shell.env('OS_DNS_API_VERSION', default="2"),
|
||||
help='DNS API version, default=' +
|
||||
DEFAULT_API_VERSION +
|
||||
' (Env: OS_DNS_API_VERSION)')
|
||||
|
||||
return parser
|
@@ -1,76 +0,0 @@
|
||||
{
|
||||
"id": "domain",
|
||||
|
||||
"$schema": "http://json-schema.org/draft-03/hyper-schema",
|
||||
|
||||
"title": "domain",
|
||||
"description": "Domain",
|
||||
"additionalProperties": false,
|
||||
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Domain Identifier",
|
||||
"pattern": "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$",
|
||||
"readonly": true
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Domain name",
|
||||
"format": "domain-name",
|
||||
"maxLength": 255,
|
||||
"required": true,
|
||||
"readonly": true
|
||||
},
|
||||
"email": {
|
||||
"type": "string",
|
||||
"description": "Hostmaster email address",
|
||||
"format": "email",
|
||||
"maxLength": 255,
|
||||
"required": true
|
||||
},
|
||||
"ttl": {
|
||||
"type": "integer",
|
||||
"description": "Time to live",
|
||||
"minimum": 1,
|
||||
"maximum": 2147483647
|
||||
},
|
||||
"serial": {
|
||||
"type": "integer",
|
||||
"description": "Serial Number",
|
||||
"minimum": 1,
|
||||
"maximum": 4294967295,
|
||||
"readonly": true
|
||||
},
|
||||
"description": {
|
||||
"type": ["string", "null"],
|
||||
"description": "Description for the Domain",
|
||||
"maxLength": 160
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"description": "Date and time of domain creation",
|
||||
"format": "date-time",
|
||||
"readonly": true
|
||||
},
|
||||
"updated_at": {
|
||||
"type": ["string", "null"],
|
||||
"description": "Date and time of last domain update",
|
||||
"format": "date-time",
|
||||
"readonly": true
|
||||
}
|
||||
},
|
||||
"links": [{
|
||||
"rel": "self",
|
||||
"href": "/domains/{id}"
|
||||
}, {
|
||||
"rel": "records",
|
||||
"href": "/domains/{id}/records"
|
||||
}, {
|
||||
"rel": "servers",
|
||||
"href": "/domains/{id}/servers"
|
||||
}, {
|
||||
"rel": "collection",
|
||||
"href": "/domains"
|
||||
}]
|
||||
}
|
@@ -1,246 +0,0 @@
|
||||
{
|
||||
"id": "record",
|
||||
|
||||
"$schema": "http://json-schema.org/draft-03/hyper-schema",
|
||||
|
||||
"title": "record",
|
||||
"description": "Record",
|
||||
"additionalProperties": false,
|
||||
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Record Identifier",
|
||||
"pattern": "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$",
|
||||
"readonly": true
|
||||
},
|
||||
"domain_id": {
|
||||
"type": "string",
|
||||
"description": "Domain Identifier",
|
||||
"pattern": "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$",
|
||||
"readonly": true
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "DNS Record Name",
|
||||
"format": "host-name",
|
||||
"maxLength": 255,
|
||||
"required": true
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "DNS Record Type",
|
||||
"enum": ["A", "AAAA", "CNAME", "MX", "SRV", "TXT", "SPF", "NS", "PTR", "SSHFP", "SOA"],
|
||||
"required": true
|
||||
},
|
||||
"data": {
|
||||
"type": "string",
|
||||
"description": "DNS Record Value",
|
||||
"maxLength": 255,
|
||||
"required": true
|
||||
},
|
||||
"priority": {
|
||||
"type": ["integer", "null"],
|
||||
"description": "DNS Record Priority",
|
||||
"minimum": 0,
|
||||
"maximum": 65535
|
||||
},
|
||||
"ttl": {
|
||||
"type": ["integer", "null"],
|
||||
"description": "Time to live",
|
||||
"minimum": 1,
|
||||
"maximum": 2147483647
|
||||
},
|
||||
"description": {
|
||||
"type": ["string", "null"],
|
||||
"description": "Description for the record",
|
||||
"maxLength": 160
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"description": "Date and time of record creation",
|
||||
"format": "date-time",
|
||||
"readonly": true
|
||||
},
|
||||
"updated_at": {
|
||||
"type": ["string", "null"],
|
||||
"description": "Date and time of last record update",
|
||||
"format": "date-time",
|
||||
"readonly": true
|
||||
}
|
||||
},
|
||||
"oneOf": [{
|
||||
"description": "An A Record",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["A"]
|
||||
},
|
||||
"data": {
|
||||
"format": "ip-address",
|
||||
"required": true
|
||||
},
|
||||
"priority": {
|
||||
"type": "null"
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"description": "An AAAA Record",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["AAAA"]
|
||||
},
|
||||
"data": {
|
||||
"format": "ipv6",
|
||||
"required": true
|
||||
},
|
||||
"priority": {
|
||||
"type": "null"
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"description": "A CNAME Record",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["CNAME"]
|
||||
},
|
||||
"data": {
|
||||
"format": "host-name",
|
||||
"required": true
|
||||
},
|
||||
"priority": {
|
||||
"type": "null"
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"description": "A MX Record",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["MX"]
|
||||
},
|
||||
"data": {
|
||||
"format": "host-name",
|
||||
"required": true
|
||||
},
|
||||
"priority": {
|
||||
"type": "integer",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"description": "A SRV Record",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["SRV"]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"pattern": "^(?:_[A-Za-z0-9_\\-]{1,62}\\.){2}"
|
||||
},
|
||||
"data": {
|
||||
"type": "string",
|
||||
"pattern": "^(?:(?:6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{1,3}|[0-9])\\s){2}(?!.{255,})((?!\\-)[A-Za-z0-9_\\-]{1,63}(?<!\\-)\\.)+$"
|
||||
},
|
||||
"priority": {
|
||||
"type": "integer",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"description": "A TXT Record",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["TXT"]
|
||||
},
|
||||
"priority": {
|
||||
"type": "null"
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"description": "A SPF Record",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["SPF"]
|
||||
},
|
||||
"priority": {
|
||||
"type": "null"
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"description": "A NS Record",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["NS"]
|
||||
},
|
||||
"data": {
|
||||
"format": "host-name",
|
||||
"required": true
|
||||
},
|
||||
"priority": {
|
||||
"type": "null"
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"description": "A PTR Record",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["PTR"]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"pattern": "^(?:(?:\\d{1,3}\\.){4}in-addr\\.arpa\\.|(?:[a-f|\\d]\\.){32}ip6\\.arpa\\.)$"
|
||||
},
|
||||
"data": {
|
||||
"format": "host-name",
|
||||
"required": true
|
||||
},
|
||||
"priority": {
|
||||
"type": "null"
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"description": "A SSHFP Record",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["SSHFP"]
|
||||
},
|
||||
"data": {
|
||||
"pattern": "^[1-2] 1 [0-9A-Fa-f]{40}$",
|
||||
"required": true
|
||||
},
|
||||
"priority": {
|
||||
"type": "null"
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"description": "A SOA Record",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["SOA"]
|
||||
},
|
||||
"priority": {
|
||||
"type": "null"
|
||||
}
|
||||
}
|
||||
}],
|
||||
"links": [{
|
||||
"rel": "self",
|
||||
"href": "/domains/{domain_id}/records/{id}"
|
||||
}, {
|
||||
"rel": "domain",
|
||||
"href": "/domains/{domain_id}"
|
||||
}, {
|
||||
"rel": "collection",
|
||||
"href": "/domains/{domain_id}/records"
|
||||
}]
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
{
|
||||
"id": "server",
|
||||
|
||||
"$schema": "http://json-schema.org/draft-03/hyper-schema",
|
||||
|
||||
"title": "server",
|
||||
"description": "Server",
|
||||
"additionalProperties": false,
|
||||
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Server Identifier",
|
||||
"pattern": "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$",
|
||||
"readonly": true
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Server DNS name",
|
||||
"format": "host-name",
|
||||
"maxLength": 255,
|
||||
"required": true
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"description": "Date and time of server creation",
|
||||
"format": "date-time",
|
||||
"readonly": true
|
||||
},
|
||||
"updated_at": {
|
||||
"type": ["string", "null"],
|
||||
"description": "Date and time of last server update",
|
||||
"format": "date-time",
|
||||
"readonly": true
|
||||
}
|
||||
},
|
||||
"links": [{
|
||||
"rel": "self",
|
||||
"href": "/servers/{id}"
|
||||
}, {
|
||||
"rel": "collection",
|
||||
"href": "/servers"
|
||||
}]
|
||||
}
|
@@ -1,252 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 logging
|
||||
import os
|
||||
import traceback
|
||||
|
||||
from cliff.app import App
|
||||
from cliff.commandmanager import CommandManager
|
||||
|
||||
from designateclient import utils
|
||||
from designateclient.version import version_info as version
|
||||
|
||||
|
||||
def env(*vars, **kwargs):
|
||||
"""Search for the first defined of possibly many env vars
|
||||
|
||||
Returns the first environment variable defined in vars, or
|
||||
returns the default defined in kwargs.
|
||||
|
||||
"""
|
||||
for v in vars:
|
||||
value = os.environ.get(v)
|
||||
if value:
|
||||
return value
|
||||
return kwargs.get('default', '')
|
||||
|
||||
|
||||
class DesignateShell(App):
|
||||
CONSOLE_MESSAGE_FORMAT = '%(levelname)s: %(message)s'
|
||||
DEFAULT_VERBOSE_LEVEL = 0
|
||||
|
||||
def __init__(self):
|
||||
super(DesignateShell, self).__init__(
|
||||
description='Designate Client',
|
||||
version=version.version_string(),
|
||||
command_manager=CommandManager('designateclient.cli'),
|
||||
)
|
||||
|
||||
self.log = logging.getLogger(__name__)
|
||||
|
||||
def build_option_parser(self, description, version):
|
||||
parser = super(DesignateShell, self).build_option_parser(
|
||||
description, version)
|
||||
|
||||
parser.add_argument('--os-username',
|
||||
default=env('OS_USERNAME'),
|
||||
help='Name used for authentication with the '
|
||||
'OpenStack Identity service. '
|
||||
'Defaults to env[OS_USERNAME].')
|
||||
|
||||
parser.add_argument('--os-user-id',
|
||||
default=env('OS_USER_ID'),
|
||||
help='User ID used for authentication with the '
|
||||
'OpenStack Identity service. '
|
||||
'Defaults to env[OS_USER_ID].')
|
||||
|
||||
parser.add_argument('--os-user-domain-id',
|
||||
default=env('OS_USER_DOMAIN_ID'),
|
||||
help='Defaults to env[OS_USER_DOMAIN_ID].')
|
||||
|
||||
parser.add_argument('--os-user-domain-name',
|
||||
default=env('OS_USER_DOMAIN_NAME'),
|
||||
help='Defaults to env[OS_USER_DOMAIN_NAME].')
|
||||
|
||||
parser.add_argument('--os-password',
|
||||
default=env('OS_PASSWORD'),
|
||||
help='Password used for authentication with the '
|
||||
'OpenStack Identity service. '
|
||||
'Defaults to env[OS_PASSWORD].')
|
||||
|
||||
parser.add_argument('--os-tenant-name',
|
||||
default=env('OS_TENANT_NAME'),
|
||||
help='Tenant to request authorization on. '
|
||||
'Defaults to env[OS_TENANT_NAME].')
|
||||
|
||||
parser.add_argument('--os-tenant-id',
|
||||
default=env('OS_TENANT_ID'),
|
||||
help='Tenant to request authorization on. '
|
||||
'Defaults to env[OS_TENANT_ID].')
|
||||
|
||||
parser.add_argument('--os-project-name',
|
||||
default=env('OS_PROJECT_NAME'),
|
||||
help='Project to request authorization on. '
|
||||
'Defaults to env[OS_PROJECT_NAME].')
|
||||
|
||||
parser.add_argument('--os-domain-name',
|
||||
default=env('OS_DOMAIN_NAME'),
|
||||
help='Project to request authorization on. '
|
||||
'Defaults to env[OS_DOMAIN_NAME].')
|
||||
|
||||
parser.add_argument('--os-domain-id',
|
||||
default=env('OS_DOMAIN_ID'),
|
||||
help='Defaults to env[OS_DOMAIN_ID].')
|
||||
|
||||
parser.add_argument('--os-project-id',
|
||||
default=env('OS_PROJECT_ID'),
|
||||
help='Project to request authorization on. '
|
||||
'Defaults to env[OS_PROJECT_ID].')
|
||||
|
||||
parser.add_argument('--os-project-domain-id',
|
||||
default=env('OS_PROJECT_DOMAIN_ID'),
|
||||
help='Defaults to env[OS_PROJECT_DOMAIN_ID].')
|
||||
|
||||
parser.add_argument('--os-project-domain-name',
|
||||
default=env('OS_PROJECT_DOMAIN_NAME'),
|
||||
help='Defaults to env[OS_PROJECT_DOMAIN_NAME].')
|
||||
|
||||
parser.add_argument('--os-auth-url',
|
||||
default=env('OS_AUTH_URL'),
|
||||
help='Specify the Identity endpoint to use for '
|
||||
'authentication. '
|
||||
'Defaults to env[OS_AUTH_URL].')
|
||||
|
||||
parser.add_argument('--os-region-name',
|
||||
default=env('OS_REGION_NAME'),
|
||||
help='Specify the region to use. '
|
||||
'Defaults to env[OS_REGION_NAME].')
|
||||
|
||||
parser.add_argument('--os-token',
|
||||
default=env('OS_SERVICE_TOKEN'),
|
||||
help='Specify an existing token to use instead of '
|
||||
'retrieving one via authentication (e.g. '
|
||||
'with username & password). '
|
||||
'Defaults to env[OS_SERVICE_TOKEN].')
|
||||
|
||||
parser.add_argument('--os-endpoint',
|
||||
default=env('OS_DNS_ENDPOINT',
|
||||
'OS_SERVICE_ENDPOINT'),
|
||||
help='Specify an endpoint to use instead of '
|
||||
'retrieving one from the service catalog '
|
||||
'(via authentication). '
|
||||
'Defaults to env[OS_DNS_ENDPOINT].')
|
||||
|
||||
parser.add_argument('--os-endpoint-type',
|
||||
default=env('OS_ENDPOINT_TYPE',
|
||||
default='publicURL'),
|
||||
help='Defaults to env[OS_ENDPOINT_TYPE].')
|
||||
|
||||
parser.add_argument('--os-service-type',
|
||||
default=env('OS_DNS_SERVICE_TYPE', default='dns'),
|
||||
help=("Defaults to env[OS_DNS_SERVICE_TYPE], or "
|
||||
"'dns'."))
|
||||
|
||||
parser.add_argument('--os-cacert',
|
||||
default=env('OS_CACERT'),
|
||||
help=('CA certificate bundle file. Defaults to '
|
||||
'env[OS_CACERT].'))
|
||||
|
||||
parser.add_argument('--insecure', action='store_true',
|
||||
help="Explicitly allow 'insecure' SSL requests.")
|
||||
|
||||
parser.add_argument('--all-tenants', action='store_true',
|
||||
help="Allows to list all domains from all "
|
||||
"tenants.")
|
||||
|
||||
parser.add_argument('--edit-managed', action='store_true',
|
||||
help='Allows to edit records that are marked as '
|
||||
'managed.')
|
||||
|
||||
return parser
|
||||
|
||||
def configure_logging(self):
|
||||
"""Configure logging for the app
|
||||
|
||||
Cliff sets some defaults we don't want so re-work it a bit
|
||||
"""
|
||||
|
||||
if self.options.debug:
|
||||
# --debug forces verbose_level 3
|
||||
# Set this here so cliff.app.configure_logging() can work
|
||||
self.options.verbose_level = 3
|
||||
|
||||
super(DesignateShell, self).configure_logging()
|
||||
root_logger = logging.getLogger('')
|
||||
|
||||
# Requests logs some stuff at INFO that we don't want
|
||||
# unless we have DEBUG
|
||||
requests_log = logging.getLogger("requests")
|
||||
requests_log.setLevel(logging.ERROR)
|
||||
|
||||
# Other modules we don't want DEBUG output for so
|
||||
# don't reset them below
|
||||
iso8601_log = logging.getLogger("iso8601")
|
||||
iso8601_log.setLevel(logging.ERROR)
|
||||
|
||||
# Set logging to the requested level
|
||||
self.dump_stack_trace = False
|
||||
if self.options.verbose_level == 0:
|
||||
# --quiet
|
||||
root_logger.setLevel(logging.ERROR)
|
||||
elif self.options.verbose_level == 1:
|
||||
# This is the default case, no --debug, --verbose or --quiet
|
||||
root_logger.setLevel(logging.WARNING)
|
||||
elif self.options.verbose_level == 2:
|
||||
# One --verbose
|
||||
root_logger.setLevel(logging.INFO)
|
||||
elif self.options.verbose_level >= 3:
|
||||
# Two or more --verbose
|
||||
root_logger.setLevel(logging.DEBUG)
|
||||
requests_log.setLevel(logging.DEBUG)
|
||||
|
||||
if self.options.debug:
|
||||
# --debug forces traceback
|
||||
self.dump_stack_trace = True
|
||||
|
||||
def initialize_app(self, argv):
|
||||
super(DesignateShell, self).initialize_app(argv)
|
||||
self.session = utils.get_session(
|
||||
auth_url=self.options.os_auth_url,
|
||||
endpoint=self.options.os_endpoint,
|
||||
domain_id=self.options.os_domain_id,
|
||||
domain_name=self.options.os_domain_name,
|
||||
project_id=self.options.os_project_id or self.options.os_tenant_id,
|
||||
project_name=(self.options.os_project_name or
|
||||
self.options.os_tenant_name),
|
||||
project_domain_name=self.options.os_project_domain_name,
|
||||
project_domain_id=self.options.os_project_domain_id,
|
||||
username=self.options.os_username,
|
||||
user_id=self.options.os_user_id,
|
||||
password=self.options.os_password,
|
||||
user_domain_id=self.options.os_user_domain_id,
|
||||
user_domain_name=self.options.os_user_domain_name,
|
||||
token=self.options.os_token,
|
||||
insecure=self.options.insecure,
|
||||
cacert=self.options.os_cacert
|
||||
)
|
||||
|
||||
def run(self, argv):
|
||||
try:
|
||||
return super(DesignateShell, self).run(argv)
|
||||
except Exception as e:
|
||||
if not logging.getLogger('').handlers:
|
||||
logging.basicConfig()
|
||||
if self.dump_stack_trace:
|
||||
self.log.error(traceback.format_exc(e))
|
||||
else:
|
||||
self.log.error('Exception raised: ' + str(e))
|
||||
return 1
|
@@ -1,144 +0,0 @@
|
||||
# Copyright 2010-2011 OpenStack Foundation
|
||||
# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 as json_
|
||||
import os
|
||||
|
||||
import fixtures
|
||||
from keystoneauth1 import session as keystone_session
|
||||
from oslotest import base as test
|
||||
from requests_mock.contrib import fixture as req_fixture
|
||||
import six
|
||||
from six.moves.urllib import parse as urlparse
|
||||
|
||||
from designateclient import client
|
||||
from designateclient.utils import AdapterWithTimeout
|
||||
|
||||
_TRUE_VALUES = ('True', 'true', '1', 'yes')
|
||||
|
||||
|
||||
class TestCase(test.BaseTestCase):
|
||||
|
||||
"""Test case base class for all unit tests."""
|
||||
|
||||
def setUp(self):
|
||||
"""Run before each test method to initialize test environment."""
|
||||
|
||||
super(TestCase, self).setUp()
|
||||
test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0)
|
||||
try:
|
||||
test_timeout = int(test_timeout)
|
||||
except ValueError:
|
||||
# If timeout value is invalid do not set a timeout.
|
||||
test_timeout = 0
|
||||
if test_timeout > 0:
|
||||
self.useFixture(fixtures.Timeout(test_timeout, gentle=True))
|
||||
|
||||
self.useFixture(fixtures.NestedTempfile())
|
||||
self.useFixture(fixtures.TempHomeDir())
|
||||
|
||||
if os.environ.get('OS_STDOUT_CAPTURE') in _TRUE_VALUES:
|
||||
stdout = self.useFixture(fixtures.StringStream('stdout')).stream
|
||||
self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout))
|
||||
if os.environ.get('OS_STDERR_CAPTURE') in _TRUE_VALUES:
|
||||
stderr = self.useFixture(fixtures.StringStream('stderr')).stream
|
||||
self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr))
|
||||
|
||||
self.log_fixture = self.useFixture(fixtures.FakeLogger())
|
||||
|
||||
|
||||
class APITestCase(TestCase):
|
||||
"""Test case base class for all unit tests."""
|
||||
|
||||
TEST_URL = "http://127.0.0.1:9001/"
|
||||
VERSION = None
|
||||
|
||||
def setUp(self):
|
||||
"""Run before each test method to initialize test environment."""
|
||||
super(TestCase, self).setUp()
|
||||
self.log_fixture = self.useFixture(fixtures.FakeLogger())
|
||||
|
||||
self.requests = self.useFixture(req_fixture.Fixture())
|
||||
self.client = self.get_client()
|
||||
|
||||
def get_base(self, base_url=None):
|
||||
if not base_url:
|
||||
base_url = '%sv%s' % (self.TEST_URL, self.VERSION)
|
||||
return base_url
|
||||
|
||||
def stub_url(self, method, parts=None, base_url=None, json=None, **kwargs):
|
||||
base_url = self.get_base(base_url)
|
||||
|
||||
if json:
|
||||
kwargs['text'] = json_.dumps(json)
|
||||
headers = kwargs.setdefault('headers', {})
|
||||
headers['Content-Type'] = 'application/json'
|
||||
|
||||
if parts:
|
||||
url = '/'.join([p.strip('/') for p in [base_url] + parts])
|
||||
else:
|
||||
url = base_url
|
||||
|
||||
url = url.replace("/?", "?")
|
||||
self.requests.register_uri(method, url, **kwargs)
|
||||
|
||||
def get_client(self, version=None, session=None):
|
||||
version = version or self.VERSION
|
||||
session = session or keystone_session.Session()
|
||||
adapted = AdapterWithTimeout(
|
||||
session=session, endpoint_override=self.get_base())
|
||||
return client.Client(version, session=adapted)
|
||||
|
||||
def assertRequestBodyIs(self, body=None, json=None):
|
||||
last_request_body = self.requests.last_request.body
|
||||
if json:
|
||||
val = json_.loads(last_request_body)
|
||||
self.assertEqual(json, val)
|
||||
elif body:
|
||||
self.assertEqual(body, last_request_body)
|
||||
|
||||
def assertQueryStringIs(self, qs=''):
|
||||
"""Verify the QueryString matches what is expected.
|
||||
|
||||
The qs parameter should be of the format \'foo=bar&abc=xyz\'
|
||||
"""
|
||||
expected = urlparse.parse_qs(qs, keep_blank_values=True)
|
||||
parts = urlparse.urlparse(self.requests.last_request.url)
|
||||
querystring = urlparse.parse_qs(parts.query, keep_blank_values=True)
|
||||
self.assertEqual(expected, querystring)
|
||||
|
||||
def assertQueryStringContains(self, **kwargs):
|
||||
"""Verify the query string contains the expected parameters.
|
||||
|
||||
This method is used to verify that the query string for the most recent
|
||||
request made contains all the parameters provided as ``kwargs``, and
|
||||
that the value of each parameter contains the value for the kwarg. If
|
||||
the value for the kwarg is an empty string (''), then all that's
|
||||
verified is that the parameter is present.
|
||||
|
||||
"""
|
||||
parts = urlparse.urlparse(self.requests.last_request.url)
|
||||
qs = urlparse.parse_qs(parts.query, keep_blank_values=True)
|
||||
|
||||
for k, v in six.iteritems(kwargs):
|
||||
self.assertIn(k, qs)
|
||||
self.assertIn(v, qs[k])
|
||||
|
||||
def assertRequestHeaderEqual(self, name, val):
|
||||
"""Verify that the last request made contains a header and its value
|
||||
|
||||
The request must have already been made.
|
||||
"""
|
||||
headers = self.requests.last_request.headers
|
||||
self.assertEqual(val, headers.get(name))
|
@@ -1,27 +0,0 @@
|
||||
# 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.
|
||||
|
||||
"""
|
||||
test_designateclient
|
||||
----------------------------------
|
||||
|
||||
Tests for `designateclient` module.
|
||||
"""
|
||||
|
||||
import designateclient
|
||||
from designateclient.tests import base
|
||||
|
||||
|
||||
class ClientTestCase(base.TestCase):
|
||||
|
||||
def test_module_version(self):
|
||||
self.assertTrue(hasattr(designateclient, '__version__'))
|
@@ -1,56 +0,0 @@
|
||||
# Copyright 2015 Rackspace Inc.
|
||||
#
|
||||
# Author: James Li <james.li@rackspace.com>
|
||||
#
|
||||
# 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 designateclient import exceptions
|
||||
from designateclient.tests import base
|
||||
|
||||
|
||||
class RemoteErrorTestCase(base.TestCase):
|
||||
response_dict = {
|
||||
'message': None,
|
||||
'code': 500,
|
||||
'type': None,
|
||||
'errors': None,
|
||||
'request_id': 1234
|
||||
}
|
||||
|
||||
def test_get_error_message(self):
|
||||
expected_msg = 'something wrong'
|
||||
self.response_dict['message'] = expected_msg
|
||||
remote_err = exceptions.RemoteError(**self.response_dict)
|
||||
self.assertEqual(expected_msg, remote_err.message)
|
||||
|
||||
def test_get_error_message_with_errors(self):
|
||||
expected_msg = "u'nodot.com' is not a 'domainname'"
|
||||
errors = {"errors": [
|
||||
{"path": ["name"],
|
||||
"message": expected_msg,
|
||||
"validator": "format",
|
||||
"validator_value": "domainname"}
|
||||
]
|
||||
}
|
||||
self.response_dict['message'] = None
|
||||
self.response_dict['errors'] = errors
|
||||
remote_err = exceptions.RemoteError(**self.response_dict)
|
||||
self.assertEqual(expected_msg, remote_err.message)
|
||||
|
||||
def test_get_error_message_with_type(self):
|
||||
expected_msg = 'invalid_object'
|
||||
self.response_dict['message'] = None
|
||||
self.response_dict['errors'] = None
|
||||
self.response_dict['type'] = expected_msg
|
||||
remote_err = exceptions.RemoteError(**self.response_dict)
|
||||
self.assertEqual(expected_msg, remote_err.message)
|
@@ -1,85 +0,0 @@
|
||||
# Copyright (c) 2015 Thales Services SAS
|
||||
# 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 uuid
|
||||
|
||||
import mock
|
||||
|
||||
|
||||
from designateclient import exceptions
|
||||
from designateclient.tests import base
|
||||
from designateclient import utils
|
||||
|
||||
|
||||
LIST_MOCK_RESPONSE = [
|
||||
{'id': '13579bdf-0000-0000-abcd-000000000001', 'name': 'abcd'},
|
||||
{'id': '13579bdf-0000-0000-baba-000000000001', 'name': 'baba'},
|
||||
{'id': '13579bdf-0000-0000-baba-000000000002', 'name': 'baba'},
|
||||
]
|
||||
|
||||
|
||||
class UtilsTestCase(base.TestCase):
|
||||
|
||||
def _find_resourceid_by_name_or_id(self, name_or_id, by_name=False):
|
||||
resource_client = mock.Mock()
|
||||
resource_client.list.return_value = LIST_MOCK_RESPONSE
|
||||
resourceid = utils.find_resourceid_by_name_or_id(
|
||||
resource_client, name_or_id)
|
||||
self.assertEqual(by_name, resource_client.list.called)
|
||||
return resourceid
|
||||
|
||||
def test_find_resourceid_with_hyphen_uuid(self):
|
||||
expected = str(uuid.uuid4())
|
||||
observed = self._find_resourceid_by_name_or_id(expected)
|
||||
self.assertEqual(expected, observed)
|
||||
|
||||
def test_find_resourceid_with_nonhyphen_uuid(self):
|
||||
expected = str(uuid.uuid4())
|
||||
fakeid = expected.replace('-', '')
|
||||
observed = self._find_resourceid_by_name_or_id(fakeid)
|
||||
self.assertEqual(expected, observed)
|
||||
|
||||
def test_find_resourceid_with_unique_resource(self):
|
||||
observed = self._find_resourceid_by_name_or_id('abcd', by_name=True)
|
||||
self.assertEqual('13579bdf-0000-0000-abcd-000000000001', observed)
|
||||
|
||||
def test_find_resourceid_with_nonexistent_resource(self):
|
||||
self.assertRaises(exceptions.ResourceNotFound,
|
||||
self._find_resourceid_by_name_or_id,
|
||||
'taz', by_name=True)
|
||||
|
||||
def test_find_resourceid_with_multiple_resources(self):
|
||||
self.assertRaises(exceptions.NoUniqueMatch,
|
||||
self._find_resourceid_by_name_or_id,
|
||||
'baba', by_name=True)
|
||||
|
||||
def test_load_schema(self):
|
||||
schema = utils.load_schema('v1', 'domain')
|
||||
self.assertIsInstance(schema, dict)
|
||||
|
||||
def test_load_schema_missing(self):
|
||||
self.assertRaises(exceptions.ResourceNotFound, utils.load_schema,
|
||||
'v1', 'missing')
|
||||
|
||||
def test_resource_string_empty_param(self):
|
||||
self.assertRaises(ValueError, utils.resource_string)
|
||||
|
||||
def test_resource_string(self):
|
||||
name = ['schemas', 'v1', 'domain.json']
|
||||
resource_string = utils.resource_string(*name)
|
||||
self.assertIsNotNone(resource_string)
|
||||
|
||||
def test_resource_string_missing(self):
|
||||
name = ['schemas', 'v1', 'missing']
|
||||
self.assertRaises(exceptions.ResourceNotFound, utils.resource_string,
|
||||
*name)
|
@@ -1,53 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@hp.com>
|
||||
#
|
||||
# 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 uuid
|
||||
|
||||
from designateclient.tests import base
|
||||
|
||||
|
||||
class CrudMixin(object):
|
||||
path_prefix = None
|
||||
|
||||
def new_ref(self, **kwargs):
|
||||
kwargs.setdefault('id', uuid.uuid4().hex)
|
||||
return kwargs
|
||||
|
||||
def stub_entity(self, method, parts=None, entity=None, id=None, **kwargs):
|
||||
if entity:
|
||||
kwargs['json'] = entity
|
||||
|
||||
if not parts:
|
||||
parts = [self.RESOURCE]
|
||||
|
||||
if self.path_prefix:
|
||||
parts.insert(0, self.path_prefix)
|
||||
|
||||
if id:
|
||||
if not parts:
|
||||
parts = []
|
||||
|
||||
parts.append(id)
|
||||
|
||||
self.stub_url(method, parts=parts, **kwargs)
|
||||
|
||||
def assertList(self, expected, actual):
|
||||
self.assertEqual(len(expected), len(actual))
|
||||
for i in expected:
|
||||
self.assertIn(i, actual)
|
||||
|
||||
|
||||
class APIV1TestCase(base.APITestCase):
|
||||
VERSION = "1"
|
@@ -1,124 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@hp.com>
|
||||
#
|
||||
# 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 designateclient.tests import test_v1
|
||||
from designateclient import utils
|
||||
from designateclient import v1
|
||||
|
||||
from keystoneauth1 import session as keystone_session
|
||||
|
||||
|
||||
class TestClient(test_v1.APIV1TestCase):
|
||||
def test_all_tenants(self):
|
||||
# Create a client with the all_tenants flag set to True
|
||||
client = v1.Client(all_tenants=True)
|
||||
|
||||
# Verify this has been picked up
|
||||
self.assertTrue(client.all_tenants)
|
||||
|
||||
def test_all_tenants_not_supplied(self):
|
||||
# Create a client without supplying any all_tenants flag
|
||||
client = v1.Client()
|
||||
|
||||
# Verify all_tenants is False
|
||||
self.assertFalse(client.all_tenants)
|
||||
self.assertIsNotNone(client.all_tenants)
|
||||
|
||||
def test_all_tenants_through_session(self):
|
||||
# Create a session with the all_tenants flag set to True
|
||||
session = utils.get_session(
|
||||
auth_url='Anything',
|
||||
endpoint='Anything',
|
||||
domain_id='Anything',
|
||||
domain_name='Anything',
|
||||
project_id='Anything',
|
||||
project_name='Anything',
|
||||
project_domain_name='Anything',
|
||||
project_domain_id='Anything',
|
||||
username='Anything',
|
||||
user_id='Anything',
|
||||
password='Anything',
|
||||
user_domain_id='Anything',
|
||||
user_domain_name='Anything',
|
||||
token=None,
|
||||
insecure=False,
|
||||
cacert=None,
|
||||
all_tenants=True)
|
||||
|
||||
# Create a client using the pre-created session
|
||||
client = v1.Client(session=session)
|
||||
|
||||
# Verify the all_tenants flag has been picked up
|
||||
self.assertTrue(client.all_tenants)
|
||||
|
||||
def test_edit_managed(self):
|
||||
# Create a client with the edit_managed flag set to True
|
||||
client = v1.Client(edit_managed=True)
|
||||
|
||||
# Verify this has been picked up
|
||||
self.assertTrue(client.edit_managed)
|
||||
|
||||
def test_edit_managed_not_supplied(self):
|
||||
# Create a client without supplying any edit_managed flag
|
||||
client = v1.Client()
|
||||
|
||||
# Verify edit_managed is False
|
||||
self.assertFalse(client.edit_managed)
|
||||
self.assertIsNotNone(client.edit_managed)
|
||||
|
||||
def test_edit_managed_through_session(self):
|
||||
# Create a session with the edit_managed flag set to True
|
||||
session = utils.get_session(
|
||||
auth_url='Anything',
|
||||
endpoint='Anything',
|
||||
domain_id='Anything',
|
||||
domain_name='Anything',
|
||||
project_id='Anything',
|
||||
project_name='Anything',
|
||||
project_domain_name='Anything',
|
||||
project_domain_id='Anything',
|
||||
username='Anything',
|
||||
user_id='Anything',
|
||||
password='Anything',
|
||||
user_domain_id='Anything',
|
||||
user_domain_name='Anything',
|
||||
token=None,
|
||||
insecure=False,
|
||||
cacert=None,
|
||||
edit_managed=True)
|
||||
|
||||
# Create a client using the pre-created session
|
||||
client = v1.Client(session=session)
|
||||
|
||||
# Verify the edit_managed flag has been picked up
|
||||
self.assertTrue(client.edit_managed)
|
||||
|
||||
def test_timeout_new_session(self):
|
||||
client = v1.Client(
|
||||
auth_url="http://127.0.0.1:22/",
|
||||
timeout=1,
|
||||
)
|
||||
assert client.session.timeout == 1
|
||||
|
||||
def test_timeout_override_session_timeout(self):
|
||||
# The adapter timeout should override the session timeout
|
||||
session = keystone_session.Session(timeout=10)
|
||||
client = v1.Client(
|
||||
auth_url="http://127.0.0.1:22/",
|
||||
session=session,
|
||||
timeout=2,
|
||||
)
|
||||
self.assertEqual(2, client.session.timeout)
|
@@ -1,30 +0,0 @@
|
||||
# Copyright 2015 NEC Corporation. All rights reserved.
|
||||
#
|
||||
# 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 mock
|
||||
from mock import patch
|
||||
|
||||
from designateclient.tests import test_v1
|
||||
from designateclient.v1 import diagnostics
|
||||
|
||||
|
||||
class TestDiagnostics(test_v1.APIV1TestCase, test_v1.CrudMixin):
|
||||
|
||||
@patch.object(diagnostics.DiagnosticsController, "ping")
|
||||
def test_ping(self, ping):
|
||||
args = mock.MagicMock()
|
||||
args.service = "foo"
|
||||
args.host = "host1"
|
||||
self.client.diagnostics.ping(args.host, args.service)
|
||||
self.client.diagnostics.ping.assert_called_with("host1", "foo")
|
@@ -1,184 +0,0 @@
|
||||
# Copyright 2015 NEC Corporation. All rights reserved.
|
||||
#
|
||||
# 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 uuid
|
||||
|
||||
from mock import patch
|
||||
|
||||
from designateclient.tests import test_v1
|
||||
from designateclient import utils
|
||||
from designateclient.v1 import domains
|
||||
from designateclient import warlock
|
||||
|
||||
Domain = warlock.model_factory(utils.load_schema('v1', 'domain'))
|
||||
|
||||
|
||||
class TestDomain(test_v1.APIV1TestCase, test_v1.CrudMixin):
|
||||
RESOURCE = 'domains'
|
||||
|
||||
def new_ref(self, **kwargs):
|
||||
ref = super(TestDomain, self).new_ref(**kwargs)
|
||||
ref.setdefault("name", uuid.uuid4().hex)
|
||||
ref.setdefault("email", "abc@example.com.")
|
||||
ref.setdefault("ttl", 3600)
|
||||
return ref
|
||||
|
||||
def test_create(self):
|
||||
ref = {"id": "89acac79-38e7-497d-807c-a011e1310438",
|
||||
"name": "domain1.com.",
|
||||
"email": "nsadmin@example.org",
|
||||
"ttl": 60}
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
response = self.client.domains.create(values["name"])
|
||||
self.assertEqual(ref['id'], response['id'])
|
||||
|
||||
def test_create_with_description(self):
|
||||
ref = {"id": "89acac79-38e7-497d-807c-a011e1310438",
|
||||
"name": "domain1.com.",
|
||||
"email": "nsadmin@example.org",
|
||||
"ttl": 60,
|
||||
"description": "fully qualified domain"}
|
||||
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
response = self.client.domains.create(values["name"])
|
||||
self.assertEqual(ref['id'], response['id'])
|
||||
|
||||
def test_create_with_description_too_long(self):
|
||||
ref = {"id": "89acac79-38e7-497d-807c-a011e1310438",
|
||||
"name": "domain1.com.",
|
||||
"email": "nsadmin@example.org",
|
||||
"ttl": 60,
|
||||
"description": "d" * 161}
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.assertRaises(ValueError, self.client.domains.create,
|
||||
values["name"])
|
||||
|
||||
def test_create_with_zero_ttl(self):
|
||||
ref = {"id": "89acac79-38e7-497d-807c-a011e1310438",
|
||||
"name": "domain1.com.",
|
||||
"email": "nsadmin@example.org",
|
||||
"ttl": 0}
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.assertRaises(ValueError, self.client.domains.create,
|
||||
values["name"])
|
||||
|
||||
def test_create_with_negative_ttl(self):
|
||||
ref = {"id": "89acac79-38e7-497d-807c-a011e1310438",
|
||||
"name": "domain1.com.",
|
||||
"email": "nsadmin@example.org",
|
||||
"ttl": -1}
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.assertRaises(ValueError, self.client.domains.create,
|
||||
values["name"])
|
||||
|
||||
def test_create_with_no_ttl(self):
|
||||
ref = {"id": "89acac79-38e7-497d-807c-a011e1310438",
|
||||
"name": "domain1.com.",
|
||||
"email": "nsadmin@example.org",
|
||||
"ttl": ""}
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.assertRaises(ValueError, self.client.domains.create,
|
||||
values["name"])
|
||||
|
||||
def test_create_with_name_too_long(self):
|
||||
ref = {"id": "89acac79-38e7-497d-807c-a011e1310438",
|
||||
"name": "domain" + "a" * 255 + ".com.",
|
||||
"email": "nsadmin@example.org",
|
||||
"ttl": 60}
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.assertRaises(ValueError, self.client.domains.create,
|
||||
values["name"])
|
||||
|
||||
def test_list(self):
|
||||
items = [
|
||||
self.new_ref(email="abc@example.org",
|
||||
id="89acac79-38e7-497d-807c-a011e1310438"),
|
||||
self.new_ref(email="root@example.org",
|
||||
id="89acac79-38e7-497d-807c-a011e1310435")
|
||||
]
|
||||
|
||||
self.stub_url("GET", parts=[self.RESOURCE], json={"domains": items})
|
||||
|
||||
listed = self.client.domains.list()
|
||||
self.assertList(items, listed)
|
||||
self.assertQueryStringIs("")
|
||||
|
||||
def test_get(self):
|
||||
ref = self.new_ref(email="abc@example.org",
|
||||
id="89acac79-38e7-497d-807c-a011e1310438")
|
||||
|
||||
self.stub_entity("GET", entity=ref, id=ref["id"])
|
||||
|
||||
response = self.client.domains.get(ref["id"])
|
||||
self.assertEqual(ref, response)
|
||||
|
||||
def test_delete(self):
|
||||
ref = self.new_ref(email="abc@example.org",
|
||||
id="89acac79-38e7-497d-807c-a011e1310438")
|
||||
|
||||
self.stub_entity("DELETE", entity=ref, id=ref["id"])
|
||||
|
||||
self.client.domains.delete(ref["id"])
|
||||
self.assertRequestBodyIs(None)
|
||||
|
||||
def test_update(self):
|
||||
ref = self.new_ref(id="89acac79-38e7-497d-807c-a011e1310438")
|
||||
|
||||
self.stub_entity("PUT", entity=ref, id=ref["id"])
|
||||
|
||||
values = ref.copy()
|
||||
|
||||
self.client.domains.update(Domain(values))
|
||||
|
||||
@patch.object(domains.DomainsController, "list_domain_servers")
|
||||
def test_list_domain_servers(self, domains_get):
|
||||
domains_get.return_value = [{"id": "foo", "name": "ns1.example.com."}]
|
||||
|
||||
ref = [{
|
||||
"id": "foo",
|
||||
"name": "ns1.example.com.",
|
||||
}]
|
||||
parts = ["domains", "foo", "servers"]
|
||||
self.stub_url("GET", parts=parts, json={"servers": ref})
|
||||
|
||||
response = self.client.domains.list_domain_servers("foo")
|
||||
self.assertEqual(ref, response)
|
@@ -1,48 +0,0 @@
|
||||
# Copyright 2015 NEC Corporation. All rights reserved.
|
||||
#
|
||||
# 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 mock
|
||||
from mock import patch
|
||||
|
||||
from designateclient.tests import test_v1
|
||||
from designateclient.v1 import quotas
|
||||
|
||||
|
||||
class TestQuota(test_v1.APIV1TestCase, test_v1.CrudMixin):
|
||||
|
||||
@patch.object(quotas.QuotasController, "get")
|
||||
def test_get(self, quota_get):
|
||||
QUOTA = {"domains": 10,
|
||||
"recordset_records": 20,
|
||||
"domain_records": 500,
|
||||
"domain_recordsets": 500}
|
||||
quota_get.return_value = QUOTA
|
||||
response = self.client.quotas.get("foo")
|
||||
self.assertEqual(QUOTA, response)
|
||||
|
||||
@patch.object(quotas.QuotasController, "update")
|
||||
def test_update(self, quota_update):
|
||||
args = mock.MagicMock()
|
||||
args.tenant_id = "1234"
|
||||
args.value = {"domains": 1000}
|
||||
self.client.quotas.update(args.tenant_id, args.value)
|
||||
self.client.quotas.update.assert_called_with(args.tenant_id,
|
||||
args.value)
|
||||
|
||||
@patch.object(quotas.QuotasController, "reset")
|
||||
def test_reset(self, quota_reset):
|
||||
args = mock.MagicMock()
|
||||
args.tenant_id = "1234"
|
||||
self.client.quotas.reset(args.tenant_id)
|
||||
self.client.quotas.reset.assert_called_with("1234")
|
@@ -1,222 +0,0 @@
|
||||
# Copyright 2015 NEC Corporation. All rights reserved.
|
||||
#
|
||||
# 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 uuid
|
||||
|
||||
from designateclient.tests import test_v1
|
||||
from designateclient import utils
|
||||
from designateclient import warlock
|
||||
|
||||
|
||||
Record = warlock.model_factory(utils.load_schema('v1', 'record'))
|
||||
|
||||
DOMAIN = {
|
||||
"id": str(uuid.uuid4()),
|
||||
"name": "example.com."
|
||||
}
|
||||
|
||||
|
||||
class TestRecords(test_v1.APIV1TestCase, test_v1.CrudMixin):
|
||||
RESOURCE = 'records'
|
||||
|
||||
def new_ref(self, **kwargs):
|
||||
ref = super(TestRecords, self).new_ref(**kwargs)
|
||||
ref.setdefault("name", uuid.uuid4().hex)
|
||||
ref.setdefault("type", "A")
|
||||
ref.setdefault("data", "10.0.0.1")
|
||||
return ref
|
||||
|
||||
def test_create_record(self):
|
||||
ref = self.new_ref(id="2e32e609-3a4f-45ba-bdef-e50eacd345ad")
|
||||
|
||||
parts = ["domains", DOMAIN["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.records.create(DOMAIN['id'], Record(values))
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_AAAA_record(self):
|
||||
ref = self.new_ref(id="11112222-3333-4444-5555-666677778888",
|
||||
type="AAAA",
|
||||
data="2001:db8:0:1234:0:5678:9:12")
|
||||
|
||||
parts = ["domains", DOMAIN["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.records.create(DOMAIN['id'], Record(values))
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_MX_record(self):
|
||||
ref = self.new_ref(id="11112222-3333-4444-5555-666677778989",
|
||||
type="MX",
|
||||
data="mail.example.com.",
|
||||
priority=10)
|
||||
|
||||
parts = ["domains", DOMAIN["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.records.create(DOMAIN['id'], Record(values))
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_CNAME_record(self):
|
||||
ref = self.new_ref(id="11112222-3333-4444-5555-666677778890",
|
||||
type="CNAME",
|
||||
data="example.com.")
|
||||
|
||||
parts = ["domains", DOMAIN["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.records.create(DOMAIN['id'], Record(values))
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_TXT_record(self):
|
||||
ref = self.new_ref(id="11112222-3333-4444-5555-666677778889",
|
||||
type="TXT",
|
||||
data="This is a TXT record")
|
||||
|
||||
parts = ["domains", DOMAIN["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.records.create(DOMAIN['id'], Record(values))
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_SRV_record(self):
|
||||
ref = self.new_ref(id="11112222-3333-4444-5555-666677778888",
|
||||
type="SRV",
|
||||
data="0 5060 sip.example.com.",
|
||||
priority=30)
|
||||
|
||||
parts = ["domains", DOMAIN["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.records.create(DOMAIN['id'], Record(values))
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_NS_record(self):
|
||||
ref = self.new_ref(id="11112222-3333-4444-5555-666677779999",
|
||||
type="NS",
|
||||
data="ns1.example.com.")
|
||||
|
||||
parts = ["domains", DOMAIN["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.records.create(DOMAIN['id'], Record(values))
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_PTR_record(self):
|
||||
ref = self.new_ref(id="11112222-3333-4444-5555-666677778891",
|
||||
type="PTR",
|
||||
data="www.example.com.")
|
||||
|
||||
parts = ["domains", DOMAIN["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.records.create(DOMAIN['id'], Record(values))
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_SPF_record(self):
|
||||
ref = self.new_ref(id="11112222-3333-4444-5555-666677778899",
|
||||
type="SPF",
|
||||
data="v=spf1 +mx a:colo.example.com/28 -all")
|
||||
|
||||
parts = ["domains", DOMAIN["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.records.create(DOMAIN['id'], Record(values))
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_SSHFP_record(self):
|
||||
ref = self.new_ref(id="11112222-3333-4444-5555-666677778888",
|
||||
type="SSHFP",
|
||||
data="2 1 6c3c958af43d953f91f40e0d84157f4fe7b4a898")
|
||||
|
||||
parts = ["domains", DOMAIN["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.records.create(DOMAIN['id'], Record(values))
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_get(self):
|
||||
ref = self.new_ref(id="2e32e609-3a4f-45ba-bdef-e50eacd345ad")
|
||||
|
||||
parts = ["domains", DOMAIN["id"], self.RESOURCE]
|
||||
self.stub_entity("GET", entity=ref, id=ref["id"], parts=parts)
|
||||
|
||||
response = self.client.records.get(DOMAIN["id"], ref["id"])
|
||||
self.assertEqual(ref, response)
|
||||
|
||||
def test_list(self):
|
||||
items = [
|
||||
self.new_ref(id="2e32e609-3a4f-45ba-bdef-e50eacd345ad"),
|
||||
self.new_ref(id="11112222-3333-4444-5555-666677778888")
|
||||
]
|
||||
|
||||
parts = ["domains", DOMAIN["id"], self.RESOURCE]
|
||||
self.stub_url("GET", parts=parts, json={"records": items})
|
||||
|
||||
listed = self.client.records.list(DOMAIN["id"])
|
||||
self.assertList(items, listed)
|
||||
self.assertQueryStringIs("")
|
||||
|
||||
def test_update(self):
|
||||
ref = self.new_ref(id="2e32e609-3a4f-45ba-bdef-e50eacd345ad",
|
||||
type="A",
|
||||
data="192.0.2.5")
|
||||
|
||||
parts = ["domains", DOMAIN["id"], self.RESOURCE]
|
||||
self.stub_entity("PUT", entity=ref, id=ref["id"], parts=parts)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.records.update(DOMAIN["id"], Record(ref))
|
||||
|
||||
def test_delete(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
parts = ["domains", DOMAIN["id"], self.RESOURCE]
|
||||
self.stub_entity("DELETE", id=ref["id"], parts=parts)
|
||||
|
||||
self.client.records.delete(DOMAIN["id"], ref["id"])
|
||||
self.assertRequestBodyIs(None)
|
@@ -1,54 +0,0 @@
|
||||
# Copyright 2015 NEC Corporation. All rights reserved.
|
||||
#
|
||||
# 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 mock
|
||||
from mock import patch
|
||||
|
||||
from designateclient.tests import test_v1
|
||||
from designateclient.v1 import reports
|
||||
|
||||
|
||||
class TestReports(test_v1.APIV1TestCase, test_v1.CrudMixin):
|
||||
|
||||
@patch.object(reports.ReportsController, "count_all")
|
||||
def test_count_all(self, count_all):
|
||||
self.client.reports.count_all()
|
||||
self.client.reports.count_all.assert_called_with()
|
||||
|
||||
@patch.object(reports.ReportsController, "count_domains")
|
||||
def test_count_domain(self, count_domains):
|
||||
self.client.reports.count_domains()
|
||||
self.client.reports.count_domains.assert_called_once_with()
|
||||
|
||||
@patch.object(reports.ReportsController, "count_tenants")
|
||||
def test_count_tenants(self, count_tenants):
|
||||
self.client.reports.count_tenants()
|
||||
self.client.reports.count_tenants.assert_called_once_with()
|
||||
|
||||
@patch.object(reports.ReportsController, "count_records")
|
||||
def test_count_records(self, count_records):
|
||||
self.client.reports.count_records()
|
||||
self.client.reports.count_records.assert_called_once_with()
|
||||
|
||||
@patch.object(reports.ReportsController, "tenants_all")
|
||||
def test_tenants_all(self, tenants_all):
|
||||
self.client.reports.tenants_all()
|
||||
self.client.reports.tenants_all.assert_called_once_with()
|
||||
|
||||
@patch.object(reports.ReportsController, "tenant_domains")
|
||||
def test_tenant_domains(self, tenant_domains):
|
||||
args = mock.MagicMock()
|
||||
args.other_tenant_id = "uuid"
|
||||
self.client.reports.tenant_domains(args.other_tenant_id)
|
||||
self.client.reports.tenant_domains.assert_called_once_with("uuid")
|
@@ -1,95 +0,0 @@
|
||||
# Copyright 2015 NEC Corporation. All rights reserved.
|
||||
#
|
||||
# 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 uuid
|
||||
|
||||
import mock
|
||||
from mock import patch
|
||||
|
||||
from designateclient.tests import test_v1
|
||||
from designateclient.v1 import servers
|
||||
|
||||
|
||||
class TestServers(test_v1.APIV1TestCase, test_v1.CrudMixin):
|
||||
RESOURCE = 'servers'
|
||||
|
||||
def new_ref(self, **kwargs):
|
||||
ref = super(TestServers, self).new_ref(**kwargs)
|
||||
ref.setdefault("name", uuid.uuid4().hex)
|
||||
return ref
|
||||
|
||||
def test_list(self):
|
||||
items = [
|
||||
self.new_ref(name="ns1.example.org.",
|
||||
id="89acac79-38e7-497d-807c-a011e1310438"),
|
||||
self.new_ref(name="ns2.example.org.",
|
||||
id="89acac79-38e7-497d-807c-a011e1310435")
|
||||
]
|
||||
|
||||
self.stub_url("GET", parts=[self.RESOURCE], json={"servers": items})
|
||||
|
||||
listed = self.client.servers.list()
|
||||
self.assertList(items, listed)
|
||||
self.assertQueryStringIs("")
|
||||
|
||||
def test_get(self):
|
||||
ref = self.new_ref(name="ns1.example.org.",
|
||||
id="89acac79-38e7-497d-807c-a011e1310438")
|
||||
|
||||
self.stub_entity("GET", entity=ref, id=ref["id"])
|
||||
|
||||
response = self.client.servers.get(ref["id"])
|
||||
self.assertEqual(ref, response)
|
||||
|
||||
def test_create(self):
|
||||
ref = {"id": "89acac79-38e7-497d-807c-a011e1310438",
|
||||
"name": "ns1.example.org."}
|
||||
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.servers.create({"name": "ns1.example.org."})
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_with_name_too_long(self):
|
||||
ref = {"id": "89acac79-38e7-497d-807c-a011e1310438",
|
||||
"name": "ns1." + "foo" * 85 + ".org."}
|
||||
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.assertRaises(ValueError, self.client.servers.create,
|
||||
{"name": "ns1.example.org."})
|
||||
|
||||
@patch.object(servers.ServersController, "update")
|
||||
def test_update(self, server_update):
|
||||
ref = self.new_ref()
|
||||
|
||||
self.stub_entity("PUT", entity=ref, id=ref["id"])
|
||||
|
||||
mock_server = mock.MagicMock()
|
||||
self.client.servers.update(mock_server)
|
||||
self.client.servers.update.assert_called_with(mock_server)
|
||||
|
||||
def test_delete(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
self.stub_entity("DELETE", id=ref["id"])
|
||||
|
||||
self.client.servers.delete(ref["id"])
|
||||
self.assertRequestBodyIs(None)
|
@@ -1,42 +0,0 @@
|
||||
# Copyright 2015 NEC Corporation. All rights reserved.
|
||||
#
|
||||
# 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 mock
|
||||
from mock import patch
|
||||
|
||||
from designateclient.tests import test_v1
|
||||
from designateclient.v1 import sync
|
||||
|
||||
|
||||
class TestSync(test_v1.APIV1TestCase, test_v1.CrudMixin):
|
||||
|
||||
@patch.object(sync.SyncController, "sync_all")
|
||||
def test_sync_all(self, sync_all):
|
||||
self.client.sync.sync_all()
|
||||
self.client.sync.sync_all.assert_called_with()
|
||||
|
||||
@patch.object(sync.SyncController, "sync_domain")
|
||||
def test_sync_domain(self, sync_domain):
|
||||
args = mock.MagicMock()
|
||||
args.tenant_id = "1234"
|
||||
self.client.sync.sync_domain(args.tenant_id)
|
||||
self.client.sync.sync_domain.assert_called_with("1234")
|
||||
|
||||
@patch.object(sync.SyncController, "sync_record")
|
||||
def test_sync_record(self, sync_record):
|
||||
args = mock.MagicMock()
|
||||
args.tenant_id = "1234"
|
||||
args.record_id = "uuid"
|
||||
self.client.sync.sync_record(args.tenant_id, args.record_id)
|
||||
self.client.sync.sync_record.assert_called_with("1234", "uuid")
|
@@ -1,29 +0,0 @@
|
||||
# Copyright 2015 NEC Corporation. All rights reserved.
|
||||
#
|
||||
# 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 mock
|
||||
from mock import patch
|
||||
|
||||
from designateclient.tests import test_v1
|
||||
from designateclient.v1 import touch
|
||||
|
||||
|
||||
class TestTouch(test_v1.APIV1TestCase, test_v1.CrudMixin):
|
||||
|
||||
@patch.object(touch.TouchController, "domain")
|
||||
def test_domain(self, domain):
|
||||
args = mock.MagicMock()
|
||||
args.domain_id = "1234"
|
||||
self.client.touch.domain(args.domain_id)
|
||||
self.client.touch.domain.assert_called_with("1234")
|
@@ -1,53 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 uuid
|
||||
|
||||
from designateclient.tests import base
|
||||
|
||||
|
||||
class CrudMixin(object):
|
||||
path_prefix = None
|
||||
|
||||
def new_ref(self, **kwargs):
|
||||
kwargs.setdefault('id', uuid.uuid4().hex)
|
||||
return kwargs
|
||||
|
||||
def stub_entity(self, method, parts=None, entity=None, id=None, **kwargs):
|
||||
if entity:
|
||||
kwargs['json'] = entity
|
||||
|
||||
if not parts:
|
||||
parts = [self.RESOURCE]
|
||||
|
||||
if self.path_prefix:
|
||||
parts.insert(0, self.path_prefix)
|
||||
|
||||
if id:
|
||||
if not parts:
|
||||
parts = []
|
||||
|
||||
parts.append(id)
|
||||
|
||||
self.stub_url(method, parts=parts, **kwargs)
|
||||
|
||||
def assertList(self, expected, actual):
|
||||
self.assertEqual(len(expected), len(actual))
|
||||
for i in expected:
|
||||
self.assertIn(i, actual)
|
||||
|
||||
|
||||
class APIV2TestCase(base.APITestCase):
|
||||
VERSION = "2"
|
@@ -1,88 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 uuid
|
||||
|
||||
from designateclient.tests import v2
|
||||
|
||||
|
||||
class TestBlacklists(v2.APIV2TestCase, v2.CrudMixin):
|
||||
RESOURCE = 'blacklists'
|
||||
|
||||
def new_ref(self, **kwargs):
|
||||
ref = super(TestBlacklists, self).new_ref(**kwargs)
|
||||
ref.setdefault("pattern", uuid.uuid4().hex)
|
||||
return ref
|
||||
|
||||
def test_create(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.blacklists.create(**values)
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_with_description(self):
|
||||
ref = self.new_ref(description="My Blacklist")
|
||||
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.blacklists.create(**values)
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_get(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
self.stub_entity("GET", entity=ref, id=ref["id"])
|
||||
|
||||
response = self.client.blacklists.get(ref["id"])
|
||||
self.assertEqual(ref, response)
|
||||
|
||||
def test_list(self):
|
||||
items = [
|
||||
self.new_ref(),
|
||||
self.new_ref()
|
||||
]
|
||||
|
||||
self.stub_url("GET", parts=[self.RESOURCE], json={"blacklists": items})
|
||||
|
||||
listed = self.client.blacklists.list()
|
||||
self.assertList(items, listed)
|
||||
self.assertQueryStringIs("")
|
||||
|
||||
def test_update(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
self.stub_entity("PATCH", entity=ref, id=ref["id"])
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.blacklists.update(ref["id"], values)
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_delete(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
self.stub_entity("DELETE", id=ref["id"])
|
||||
|
||||
self.client.blacklists.delete(ref["id"])
|
||||
self.assertRequestBodyIs(None)
|
@@ -1,46 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Federico Ceratto <federico.ceratto@hp.com>
|
||||
#
|
||||
# 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 keystoneauth1 import adapter
|
||||
from keystoneauth1 import session as keystone_session
|
||||
|
||||
from designateclient.tests.base import TestCase
|
||||
from designateclient.v2.client import Client
|
||||
|
||||
|
||||
class TestClient(TestCase):
|
||||
def test_init(self):
|
||||
self.assertRaises(ValueError, Client)
|
||||
|
||||
def test_init_with_session(self):
|
||||
session = keystone_session.Session()
|
||||
adapted = adapter.Adapter(session=session)
|
||||
client = Client(session=adapted)
|
||||
assert client.session
|
||||
|
||||
def test_init_with_session_timeout(self):
|
||||
session = keystone_session.Session()
|
||||
client = Client(
|
||||
session=session,
|
||||
timeout=1)
|
||||
assert client.session.timeout == 1
|
||||
|
||||
def test_init_with_auth(self):
|
||||
session = keystone_session.Session()
|
||||
client = Client(
|
||||
auth='http://127.0.0.1:22/',
|
||||
session=session)
|
||||
assert client.session.auth
|
@@ -1,25 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 designateclient.tests import v2
|
||||
|
||||
|
||||
class TestLimits(v2.APIV2TestCase, v2.CrudMixin):
|
||||
def test_get(self):
|
||||
ref = {"max_zones": "foo"}
|
||||
self.stub_url("GET", parts=["limits"], json=ref)
|
||||
|
||||
limits = self.client.limits.get()
|
||||
self.assertEqual(ref, limits)
|
@@ -1,35 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 mock import patch
|
||||
|
||||
from designateclient.tests import v2
|
||||
from designateclient.v2 import zones
|
||||
|
||||
|
||||
class TestLimits(v2.APIV2TestCase, v2.CrudMixin):
|
||||
@patch.object(zones.ZoneController, "list")
|
||||
def test_get(self, zones_get):
|
||||
zones_get.return_value = [{"id": "foo"}]
|
||||
|
||||
ref = [{
|
||||
"hostname": "ns1.example.com.",
|
||||
"priority": 1
|
||||
}]
|
||||
parts = ["zones", "foo", "nameservers"]
|
||||
self.stub_url("GET", parts=parts, json={"nameservers": ref})
|
||||
|
||||
response = self.client.nameservers.list("foo")
|
||||
self.assertEqual(ref, response)
|
@@ -1,237 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 uuid
|
||||
|
||||
from mock import patch
|
||||
import testtools
|
||||
|
||||
from designateclient import exceptions
|
||||
from designateclient.tests import v2
|
||||
from designateclient.v2 import zones
|
||||
|
||||
ZONE = {
|
||||
"id": str(uuid.uuid4()),
|
||||
"name": "example.com."
|
||||
}
|
||||
|
||||
|
||||
class TestRecordSets(v2.APIV2TestCase, v2.CrudMixin):
|
||||
RESOURCE = 'recordsets'
|
||||
|
||||
def new_ref(self, **kwargs):
|
||||
ref = super(TestRecordSets, self).new_ref(**kwargs)
|
||||
ref.setdefault("name", uuid.uuid4().hex)
|
||||
ref.setdefault("type", "A")
|
||||
ref.setdefault("records", ["10.0.0.1"])
|
||||
return ref
|
||||
|
||||
def test_create_absolute_with_zone_dict(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
parts = ["zones", ZONE["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.recordsets.create(
|
||||
ZONE,
|
||||
"%s.%s" % (values["name"], ZONE["name"]),
|
||||
values["type"],
|
||||
values["records"])
|
||||
|
||||
values["name"] = "%s.%s" % (ref["name"], ZONE["name"])
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
@patch.object(zones.ZoneController, "get")
|
||||
def test_create_absolute_with_zone_name(self, zone_get):
|
||||
ref = self.new_ref()
|
||||
|
||||
zone_get.return_value = ZONE
|
||||
|
||||
parts = ["zones", ZONE["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.recordsets.create(
|
||||
ZONE["name"],
|
||||
"%s.%s" % (values["name"], ZONE["name"]),
|
||||
values["type"],
|
||||
values["records"])
|
||||
|
||||
values["name"] = "%s.%s" % (ref["name"], ZONE["name"])
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
@patch.object(zones.ZoneController, "get")
|
||||
def test_create_non_absolute_with_zone_name(self, zone_get):
|
||||
ref = self.new_ref()
|
||||
|
||||
zone_get.return_value = ZONE
|
||||
|
||||
parts = ["zones", ZONE["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.recordsets.create(
|
||||
ZONE["name"],
|
||||
values["name"],
|
||||
values["type"],
|
||||
values["records"])
|
||||
|
||||
values["name"] = "%s.%s" % (ref["name"], ZONE["name"])
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
@patch.object(zones.ZoneController, "list")
|
||||
def test_create_non_absolute_with_zone_name_non_unique(self, zone_list):
|
||||
zone_list.return_value = [
|
||||
1,
|
||||
2
|
||||
]
|
||||
|
||||
ref = self.new_ref()
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
with testtools.ExpectedException(exceptions.NoUniqueMatch):
|
||||
self.client.recordsets.create(
|
||||
ZONE["name"],
|
||||
"%s.%s" % (values["name"], ZONE["name"]),
|
||||
values["type"],
|
||||
values["records"])
|
||||
|
||||
def test_create_absolute_with_zone_id(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
parts = ["zones", ZONE["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.recordsets.create(
|
||||
ZONE["id"],
|
||||
"%s.%s" % (values["name"], ZONE["name"]),
|
||||
values["type"],
|
||||
values["records"])
|
||||
|
||||
values["name"] = "%s.%s" % (ref["name"], ZONE["name"])
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
@patch.object(zones.ZoneController, "get")
|
||||
def test_create_non_absolute_with_zone_id(self, zone_get):
|
||||
ref = self.new_ref()
|
||||
|
||||
zone_get.return_value = ZONE
|
||||
|
||||
parts = ["zones", ZONE["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.recordsets.create(
|
||||
ZONE["id"],
|
||||
values["name"],
|
||||
values["type"],
|
||||
values["records"])
|
||||
|
||||
values["name"] = "%s.%s" % (ref["name"], ZONE["name"])
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_with_description(self):
|
||||
ref = self.new_ref(description="Foo")
|
||||
|
||||
parts = ["zones", ZONE["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.recordsets.create(
|
||||
ZONE["id"],
|
||||
"%s.%s" % (values["name"], ZONE["name"]),
|
||||
values["type"],
|
||||
values["records"],
|
||||
description=values["description"])
|
||||
|
||||
values["name"] = "%s.%s" % (ref["name"], ZONE["name"])
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_with_ttl(self):
|
||||
ref = self.new_ref(ttl=60)
|
||||
|
||||
parts = ["zones", ZONE["id"], self.RESOURCE]
|
||||
self.stub_url("POST", parts=parts, json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.recordsets.create(
|
||||
ZONE["id"],
|
||||
"%s.%s" % (values["name"], ZONE["name"]),
|
||||
values["type"],
|
||||
values["records"],
|
||||
ttl=values["ttl"])
|
||||
|
||||
values["name"] = "%s.%s" % (ref["name"], ZONE["name"])
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_get(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
parts = ["zones", ZONE["id"], self.RESOURCE]
|
||||
self.stub_entity("GET", entity=ref, id=ref["id"], parts=parts)
|
||||
|
||||
response = self.client.recordsets.get(ZONE["id"], ref["id"])
|
||||
self.assertEqual(ref, response)
|
||||
|
||||
def test_list(self):
|
||||
items = [
|
||||
self.new_ref(),
|
||||
self.new_ref()
|
||||
]
|
||||
|
||||
parts = ["zones", ZONE["id"], self.RESOURCE]
|
||||
self.stub_url("GET", parts=parts, json={"recordsets": items})
|
||||
|
||||
listed = self.client.recordsets.list(ZONE["id"])
|
||||
self.assertList(items, listed)
|
||||
self.assertQueryStringIs("")
|
||||
|
||||
def test_update(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
parts = ["zones", ZONE["id"], self.RESOURCE]
|
||||
self.stub_entity("PUT", entity=ref, id=ref["id"], parts=parts)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.recordsets.update(ZONE["id"], ref["id"], values)
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_delete(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
parts = ["zones", ZONE["id"], self.RESOURCE]
|
||||
self.stub_entity("DELETE", id=ref["id"], parts=parts)
|
||||
|
||||
self.client.recordsets.delete(ZONE["id"], ref["id"])
|
||||
self.assertRequestBodyIs(None)
|
@@ -1,62 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 uuid
|
||||
|
||||
from designateclient.tests import v2
|
||||
|
||||
FIP_ID = '%s:%s' % (str(uuid.uuid4()), "RegionOne")
|
||||
|
||||
|
||||
class TestFloatingIP(v2.APIV2TestCase, v2.CrudMixin):
|
||||
def test_set(self):
|
||||
name = "foo.com."
|
||||
|
||||
ref = {
|
||||
"ptrdname": name,
|
||||
"description": "foo"
|
||||
}
|
||||
|
||||
parts = ["reverse", "floatingips", FIP_ID]
|
||||
self.stub_url("PATCH", parts=parts, json=ref)
|
||||
|
||||
self.client.floatingips.set(FIP_ID, name, "foo")
|
||||
|
||||
def test_list(self):
|
||||
ref = [
|
||||
{"ptrdname": "foo.com."}
|
||||
]
|
||||
|
||||
self.stub_url("GET", parts=["reverse", "floatingips"],
|
||||
json={"floatingips": ref})
|
||||
|
||||
self.client.floatingips.list()
|
||||
|
||||
def test_get(self):
|
||||
ref = {
|
||||
"ptrdname": "foo.com."
|
||||
}
|
||||
|
||||
parts = ["reverse", "floatingips", FIP_ID]
|
||||
self.stub_url("GET", parts=parts, json=ref)
|
||||
|
||||
self.client.floatingips.get(FIP_ID)
|
||||
|
||||
def test_unset(self):
|
||||
parts = ["reverse", "floatingips", FIP_ID]
|
||||
self.stub_url("PATCH", parts=parts, json={"ptdrname": None})
|
||||
|
||||
self.client.floatingips.unset(FIP_ID)
|
||||
self.assertRequestBodyIs(None)
|
@@ -1,46 +0,0 @@
|
||||
# Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 designateclient.tests import v2
|
||||
|
||||
|
||||
class TestServiceStatuses(v2.APIV2TestCase, v2.CrudMixin):
|
||||
RESOURCE = 'service_statuses'
|
||||
|
||||
def new_ref(self, **kwargs):
|
||||
ref = super(TestServiceStatuses, self).new_ref(**kwargs)
|
||||
ref["name"] = "foo"
|
||||
return ref
|
||||
|
||||
def test_get(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
self.stub_entity("GET", entity=ref, id=ref["id"])
|
||||
|
||||
response = self.client.service_statuses.get(ref["id"])
|
||||
self.assertEqual(ref, response)
|
||||
|
||||
def test_list(self):
|
||||
items = [
|
||||
self.new_ref(),
|
||||
self.new_ref()
|
||||
]
|
||||
|
||||
self.stub_url("GET", parts=[self.RESOURCE],
|
||||
json={"service_statuses": items})
|
||||
|
||||
listed = self.client.service_statuses.list()
|
||||
self.assertList(items, listed)
|
||||
self.assertQueryStringIs("")
|
@@ -1,109 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Federico Ceratto <federico.ceratto@hp.com>
|
||||
#
|
||||
# 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 keystoneauth1.identity import generic
|
||||
from keystoneauth1 import session as keystone_session
|
||||
from mock import Mock
|
||||
|
||||
from designateclient.tests import v2
|
||||
from designateclient.v2.client import Client
|
||||
|
||||
|
||||
def create_session(timeout=None):
|
||||
auth = generic.Password(auth_url='', username='', password='',
|
||||
tenant_name='')
|
||||
return keystone_session.Session(auth=auth, timeout=timeout)
|
||||
|
||||
|
||||
class TestTimeout(v2.APIV2TestCase, v2.CrudMixin):
|
||||
|
||||
def setUp(self):
|
||||
super(TestTimeout, self).setUp()
|
||||
|
||||
# Mock methods in KeyStone's Session
|
||||
self._saved_methods = (
|
||||
keystone_session.Session.get_auth_headers,
|
||||
keystone_session.Session.get_endpoint,
|
||||
keystone_session.Session._send_request,
|
||||
)
|
||||
|
||||
resp = Mock()
|
||||
resp.text = ''
|
||||
resp.status_code = 200
|
||||
|
||||
keystone_session.Session.get_auth_headers = Mock(
|
||||
return_value=[]
|
||||
)
|
||||
keystone_session.Session.get_endpoint = Mock(
|
||||
return_value='foo'
|
||||
)
|
||||
keystone_session.Session._send_request = Mock(
|
||||
return_value=resp,
|
||||
)
|
||||
self.mock_send_request = keystone_session.Session._send_request
|
||||
|
||||
def tearDown(self):
|
||||
super(TestTimeout, self).tearDown()
|
||||
(
|
||||
keystone_session.Session.get_auth_headers,
|
||||
keystone_session.Session.get_endpoint,
|
||||
keystone_session.Session._send_request,
|
||||
) = self._saved_methods
|
||||
|
||||
def _call_request_and_check_timeout(self, client, timeout):
|
||||
"""call the mocked _send_request() and check if the timeout was set
|
||||
"""
|
||||
client.limits.get()
|
||||
self.assertTrue(self.mock_send_request.called)
|
||||
kw = self.mock_send_request.call_args[1]
|
||||
if timeout is None:
|
||||
self.assertNotIn('timeout', kw)
|
||||
else:
|
||||
self.assertEqual(timeout, kw['timeout'])
|
||||
|
||||
def test_no_timeout(self):
|
||||
session = create_session(timeout=None)
|
||||
client = Client(session=session)
|
||||
self.assertIsNone(session.timeout)
|
||||
self.assertIsNone(client.session.timeout)
|
||||
self._call_request_and_check_timeout(client, None)
|
||||
|
||||
def test_timeout_in_session(self):
|
||||
session = create_session(timeout=1)
|
||||
client = Client(session=session)
|
||||
self.assertEqual(1, session.timeout)
|
||||
self.assertIsNone(client.session.timeout)
|
||||
self._call_request_and_check_timeout(client, 1)
|
||||
|
||||
def test_timeout_override_session_timeout(self):
|
||||
# The adapter timeout should override the session timeout
|
||||
session = create_session(timeout=10)
|
||||
self.assertEqual(10, session.timeout)
|
||||
client = Client(session=session, timeout=2)
|
||||
self.assertEqual(2, client.session.timeout)
|
||||
self._call_request_and_check_timeout(client, 2)
|
||||
|
||||
def test_timeout_update(self):
|
||||
session = create_session(timeout=1)
|
||||
client = Client(session=session)
|
||||
self.assertEqual(1, session.timeout)
|
||||
self.assertIsNone(client.session.timeout)
|
||||
self._call_request_and_check_timeout(client, 1)
|
||||
|
||||
session.timeout = 2
|
||||
self.assertEqual(2, session.timeout)
|
||||
|
||||
self._call_request_and_check_timeout(client, 2)
|
@@ -1,103 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 uuid
|
||||
|
||||
from designateclient.tests import v2
|
||||
|
||||
|
||||
class TestTlds(v2.APIV2TestCase, v2.CrudMixin):
|
||||
RESOURCE = 'tlds'
|
||||
|
||||
def new_ref(self, **kwargs):
|
||||
ref = super(TestTlds, self).new_ref(**kwargs)
|
||||
ref.setdefault("name", uuid.uuid4().hex)
|
||||
return ref
|
||||
|
||||
def test_create(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.tlds.create(**values)
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_with_description(self):
|
||||
ref = self.new_ref(description="My TLD")
|
||||
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.tlds.create(**values)
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_get(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
self.stub_entity("GET", entity=ref, id=ref["id"])
|
||||
|
||||
response = self.client.tlds.get(ref["id"])
|
||||
self.assertEqual(ref, response)
|
||||
|
||||
def test_get_by_name(self):
|
||||
ref = self.new_ref(name="www")
|
||||
|
||||
self.stub_entity("GET", entity=ref, id=ref["id"])
|
||||
self.stub_url("GET", parts=[self.RESOURCE], json={"tlds": [ref]})
|
||||
|
||||
response = self.client.tlds.get(ref['name'])
|
||||
|
||||
self.assertEqual("GET", self.requests.request_history[0].method)
|
||||
self.assertEqual(
|
||||
"http://127.0.0.1:9001/v2/tlds?name=www",
|
||||
self.requests.request_history[0].url)
|
||||
|
||||
self.assertEqual(ref, response)
|
||||
|
||||
def test_list(self):
|
||||
items = [
|
||||
self.new_ref(),
|
||||
self.new_ref()
|
||||
]
|
||||
|
||||
self.stub_url("GET", parts=[self.RESOURCE], json={"tlds": items})
|
||||
|
||||
listed = self.client.tlds.list()
|
||||
self.assertList(items, listed)
|
||||
self.assertQueryStringIs("")
|
||||
|
||||
def test_update(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
self.stub_entity("PATCH", entity=ref, id=ref["id"])
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.tlds.update(ref["id"], values)
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_delete(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
self.stub_entity("DELETE", id=ref["id"])
|
||||
|
||||
self.client.tlds.delete(ref["id"])
|
||||
self.assertRequestBodyIs(None)
|
@@ -1,382 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 time
|
||||
import uuid
|
||||
|
||||
from designateclient.tests import v2
|
||||
|
||||
|
||||
class TestZones(v2.APIV2TestCase, v2.CrudMixin):
|
||||
RESOURCE = 'zones'
|
||||
|
||||
def new_ref(self, **kwargs):
|
||||
ref = super(TestZones, self).new_ref(**kwargs)
|
||||
ref.setdefault("name", uuid.uuid4().hex)
|
||||
ref.setdefault("type", "PRIMARY")
|
||||
return ref
|
||||
|
||||
def test_create_with_description(self):
|
||||
ref = self.new_ref(email="root@example.com", description="Foo")
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.zones.create(
|
||||
values["name"],
|
||||
email=values["email"],
|
||||
description=values["description"])
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_primary(self):
|
||||
ref = self.new_ref(email="root@example.com")
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.zones.create(
|
||||
values["name"],
|
||||
email=values["email"])
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_primary_with_ttl(self):
|
||||
ref = self.new_ref(email="root@example.com", ttl=60)
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.zones.create(
|
||||
values["name"],
|
||||
email=values["email"],
|
||||
ttl=values["ttl"])
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_create_secondary(self):
|
||||
ref = self.new_ref(type="SECONDARY", masters=["10.0.0.1"])
|
||||
self.stub_url("POST", parts=[self.RESOURCE], json=ref)
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.zones.create(
|
||||
values["name"],
|
||||
type_=values["type"],
|
||||
masters=values["masters"])
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_get(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
self.stub_entity("GET", entity=ref, id=ref["id"])
|
||||
|
||||
response = self.client.zones.get(ref["id"])
|
||||
self.assertEqual(ref, response)
|
||||
|
||||
def test_list(self):
|
||||
items = [
|
||||
self.new_ref(),
|
||||
self.new_ref()
|
||||
]
|
||||
|
||||
self.stub_url("GET", parts=[self.RESOURCE], json={"zones": items})
|
||||
|
||||
listed = self.client.zones.list()
|
||||
self.assertList(items, listed)
|
||||
self.assertQueryStringIs("")
|
||||
|
||||
def test_update(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
self.stub_entity("PATCH", entity=ref, id=ref["id"])
|
||||
|
||||
values = ref.copy()
|
||||
del values["id"]
|
||||
|
||||
self.client.zones.update(ref["id"], values)
|
||||
self.assertRequestBodyIs(json=values)
|
||||
|
||||
def test_delete(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
self.stub_entity("DELETE", id=ref["id"])
|
||||
|
||||
self.client.zones.delete(ref["id"])
|
||||
self.assertRequestBodyIs(None)
|
||||
|
||||
def test_task_abandon(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
parts = [self.RESOURCE, ref["id"], "tasks", "abandon"]
|
||||
self.stub_url("POST", parts=parts)
|
||||
|
||||
self.client.zones.abandon(ref["id"])
|
||||
self.assertRequestBodyIs(None)
|
||||
|
||||
def test_task_axfr(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
parts = [self.RESOURCE, ref["id"], "tasks", "xfr"]
|
||||
self.stub_url("POST", parts=parts)
|
||||
|
||||
self.client.zones.axfr(ref["id"])
|
||||
self.assertRequestBodyIs(None)
|
||||
|
||||
|
||||
class TestZoneTransfers(v2.APIV2TestCase, v2.CrudMixin):
|
||||
def test_create_request(self):
|
||||
zone = "098bee04-fe30-4a83-8ccd-e0c496755816"
|
||||
project = "123"
|
||||
|
||||
ref = {
|
||||
"target_project_id": project
|
||||
}
|
||||
|
||||
parts = ["zones", zone, "tasks", "transfer_requests"]
|
||||
self.stub_url('POST', parts=parts, json=ref)
|
||||
|
||||
self.client.zone_transfers.create_request(zone, project)
|
||||
self.assertRequestBodyIs(json=ref)
|
||||
|
||||
def test_create_request_with_description(self):
|
||||
zone = "098bee04-fe30-4a83-8ccd-e0c496755816"
|
||||
project = "123"
|
||||
|
||||
ref = {
|
||||
"target_project_id": project,
|
||||
"description": "My Foo"
|
||||
}
|
||||
|
||||
parts = ["zones", zone, "tasks", "transfer_requests"]
|
||||
self.stub_url('POST', parts=parts, json=ref)
|
||||
|
||||
self.client.zone_transfers.create_request(
|
||||
zone, project, ref["description"])
|
||||
self.assertRequestBodyIs(json=ref)
|
||||
|
||||
def test_get_request(self):
|
||||
transfer = "098bee04-fe30-4a83-8ccd-e0c496755816"
|
||||
project = "098bee04-fe30-4a83-8ccd-e0c496755817"
|
||||
|
||||
ref = {
|
||||
"target_project_id": project
|
||||
}
|
||||
|
||||
parts = ["zones", "tasks", "transfer_requests", transfer]
|
||||
self.stub_url('GET', parts=parts, json=ref)
|
||||
|
||||
self.client.zone_transfers.get_request(transfer)
|
||||
self.assertRequestBodyIs("")
|
||||
|
||||
def test_list_request(self):
|
||||
project = "098bee04-fe30-4a83-8ccd-e0c496755817"
|
||||
|
||||
ref = [{
|
||||
"target_project_id": project
|
||||
}]
|
||||
|
||||
parts = ["zones", "tasks", "transfer_requests"]
|
||||
self.stub_url('GET', parts=parts, json={"transfer_requests": ref})
|
||||
|
||||
self.client.zone_transfers.list_requests()
|
||||
self.assertRequestBodyIs("")
|
||||
|
||||
def test_update_request(self):
|
||||
transfer = "098bee04-fe30-4a83-8ccd-e0c496755816"
|
||||
project = "098bee04-fe30-4a83-8ccd-e0c496755817"
|
||||
|
||||
ref = {
|
||||
"target_project_id": project
|
||||
}
|
||||
|
||||
parts = ["zones", "tasks", "transfer_requests", transfer]
|
||||
self.stub_url('PATCH', parts=parts, json=ref)
|
||||
|
||||
self.client.zone_transfers.update_request(transfer, ref)
|
||||
self.assertRequestBodyIs(json=ref)
|
||||
|
||||
def test_delete_request(self):
|
||||
transfer = "098bee04-fe30-4a83-8ccd-e0c496755816"
|
||||
|
||||
parts = ["zones", "tasks", "transfer_requests", transfer]
|
||||
self.stub_url('DELETE', parts=parts)
|
||||
|
||||
self.client.zone_transfers.delete_request(transfer)
|
||||
self.assertRequestBodyIs("")
|
||||
|
||||
def test_accept_request(self):
|
||||
transfer = "098bee04-fe30-4a83-8ccd-e0c496755816"
|
||||
key = "foo123"
|
||||
|
||||
ref = {
|
||||
"status": "COMPLETE"
|
||||
}
|
||||
|
||||
parts = ["zones", "tasks", "transfer_accepts"]
|
||||
self.stub_url('POST', parts=parts, json=ref)
|
||||
|
||||
request = {
|
||||
"key": key,
|
||||
"zone_transfer_request_id": transfer
|
||||
}
|
||||
self.client.zone_transfers.accept_request(transfer, key)
|
||||
self.assertRequestBodyIs(json=request)
|
||||
|
||||
def test_get_accept(self):
|
||||
accept_id = "098bee04-fe30-4a83-8ccd-e0c496755816"
|
||||
|
||||
ref = {
|
||||
"status": "COMPLETE"
|
||||
}
|
||||
|
||||
parts = ["zones", "tasks", "transfer_accepts", accept_id]
|
||||
self.stub_url('GET', parts=parts, json=ref)
|
||||
|
||||
response = self.client.zone_transfers.get_accept(accept_id)
|
||||
self.assertEqual(ref, response)
|
||||
|
||||
def test_list_accepts(self):
|
||||
accept_id = "098bee04-fe30-4a83-8ccd-e0c496755816"
|
||||
|
||||
ref = {
|
||||
"id": accept_id,
|
||||
"status": "COMPLETE"
|
||||
}
|
||||
|
||||
parts = ["zones", "tasks", "transfer_accepts"]
|
||||
self.stub_url('GET', parts=parts, json={"transfer_accepts": ref})
|
||||
|
||||
self.client.zone_transfers.list_accepts()
|
||||
self.assertRequestBodyIs("")
|
||||
|
||||
|
||||
class TestZoneExports(v2.APIV2TestCase, v2.CrudMixin):
|
||||
def new_ref(self, **kwargs):
|
||||
ref = super(TestZoneExports, self).new_ref(**kwargs)
|
||||
ref.setdefault("zone_id", uuid.uuid4().hex)
|
||||
ref.setdefault("created_at", time.strftime("%c"))
|
||||
ref.setdefault("updated_at", time.strftime("%c"))
|
||||
ref.setdefault("status", 'PENDING')
|
||||
ref.setdefault("version", '1')
|
||||
return ref
|
||||
|
||||
def test_create_export(self):
|
||||
zone = uuid.uuid4().hex
|
||||
ref = {}
|
||||
|
||||
parts = ["zones", zone, "tasks", "export"]
|
||||
self.stub_url('POST', parts=parts, json=ref)
|
||||
|
||||
self.client.zone_exports.create(zone)
|
||||
self.assertRequestBodyIs(json=ref)
|
||||
|
||||
def test_get_export(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
parts = ["zones", "tasks", "exports", ref["id"]]
|
||||
self.stub_url('GET', parts=parts, json=ref)
|
||||
self.stub_entity("GET", parts=parts, entity=ref, id=ref["id"])
|
||||
|
||||
response = self.client.zone_exports.get_export_record(ref["id"])
|
||||
self.assertEqual(ref, response)
|
||||
|
||||
def test_list_exports(self):
|
||||
items = [
|
||||
self.new_ref(),
|
||||
self.new_ref()
|
||||
]
|
||||
|
||||
parts = ["zones", "tasks", "exports"]
|
||||
self.stub_url('GET', parts=parts, json={"exports": items})
|
||||
|
||||
listed = self.client.zone_exports.list()
|
||||
self.assertList(items, listed["exports"])
|
||||
self.assertQueryStringIs("")
|
||||
|
||||
def test_delete_export(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
parts = ["zones", "tasks", "exports", ref["id"]]
|
||||
self.stub_url('DELETE', parts=parts, json=ref)
|
||||
self.stub_entity("DELETE", parts=parts, id=ref["id"])
|
||||
|
||||
self.client.zone_exports.delete(ref["id"])
|
||||
self.assertRequestBodyIs(None)
|
||||
|
||||
def test_get_export_file(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
parts = ["zones", "tasks", "exports", ref["id"], "export"]
|
||||
self.stub_url('GET', parts=parts, json=ref)
|
||||
self.stub_entity("GET", parts=parts, entity=ref, id=ref["id"])
|
||||
|
||||
response = self.client.zone_exports.get_export(ref["id"])
|
||||
self.assertEqual(ref, response)
|
||||
|
||||
|
||||
class TestZoneImports(v2.APIV2TestCase, v2.CrudMixin):
|
||||
def new_ref(self, **kwargs):
|
||||
ref = super(TestZoneImports, self).new_ref(**kwargs)
|
||||
ref.setdefault("zone_id", uuid.uuid4().hex)
|
||||
ref.setdefault("created_at", time.strftime("%c"))
|
||||
ref.setdefault("updated_at", time.strftime("%c"))
|
||||
ref.setdefault("status", 'PENDING')
|
||||
ref.setdefault("message", 'Importing...')
|
||||
ref.setdefault("version", '1')
|
||||
return ref
|
||||
|
||||
def test_create_import(self):
|
||||
zonefile = '$ORIGIN example.com'
|
||||
|
||||
parts = ["zones", "tasks", "imports"]
|
||||
self.stub_url('POST', parts=parts, json=zonefile)
|
||||
|
||||
self.client.zone_imports.create(zonefile)
|
||||
self.assertRequestBodyIs(body=zonefile)
|
||||
|
||||
def test_get_import(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
parts = ["zones", "tasks", "imports", ref["id"]]
|
||||
self.stub_url('GET', parts=parts, json=ref)
|
||||
self.stub_entity("GET", parts=parts, entity=ref, id=ref["id"])
|
||||
|
||||
response = self.client.zone_imports.get_import_record(ref["id"])
|
||||
self.assertEqual(ref, response)
|
||||
|
||||
def test_list_imports(self):
|
||||
items = [
|
||||
self.new_ref(),
|
||||
self.new_ref()
|
||||
]
|
||||
|
||||
parts = ["zones", "tasks", "imports"]
|
||||
self.stub_url('GET', parts=parts, json={"imports": items})
|
||||
|
||||
listed = self.client.zone_imports.list()
|
||||
self.assertList(items, listed["imports"])
|
||||
self.assertQueryStringIs("")
|
||||
|
||||
def test_delete_import(self):
|
||||
ref = self.new_ref()
|
||||
|
||||
parts = ["zones", "tasks", "imports", ref["id"]]
|
||||
self.stub_url('DELETE', parts=parts, json=ref)
|
||||
self.stub_entity("DELETE", parts=parts, id=ref["id"])
|
||||
|
||||
self.client.zone_imports.delete(ref["id"])
|
||||
self.assertRequestBodyIs(None)
|
@@ -1,198 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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
|
||||
import os
|
||||
import uuid
|
||||
|
||||
from debtcollector import removals
|
||||
from keystoneauth1 import adapter
|
||||
from keystoneauth1.identity import generic
|
||||
from keystoneauth1 import session as ks_session
|
||||
from keystoneauth1 import token_endpoint
|
||||
import pkg_resources
|
||||
import six
|
||||
|
||||
from designateclient import exceptions
|
||||
|
||||
|
||||
def resource_string(*args, **kwargs):
|
||||
if len(args) == 0:
|
||||
raise ValueError()
|
||||
|
||||
package = kwargs.pop('package', None)
|
||||
|
||||
if not package:
|
||||
package = 'designateclient'
|
||||
|
||||
resource_path = os.path.join('resources', *args)
|
||||
|
||||
if not pkg_resources.resource_exists(package, resource_path):
|
||||
raise exceptions.ResourceNotFound('Could not find the requested '
|
||||
'resource: %s' % resource_path)
|
||||
|
||||
return pkg_resources.resource_string(package, resource_path)
|
||||
|
||||
|
||||
def load_schema(version, name, package=None):
|
||||
schema_string = resource_string('schemas', version, '%s.json' % name,
|
||||
package=package)
|
||||
|
||||
return json.loads(schema_string.decode('utf-8'))
|
||||
|
||||
|
||||
def get_item_properties(item, fields, mixed_case_fields=[], formatters={}):
|
||||
"""Return a tuple containing the item properties.
|
||||
|
||||
:param item: a single item resource (e.g. Server, Tenant, etc)
|
||||
:param fields: tuple of strings with the desired field names
|
||||
:param mixed_case_fields: tuple of field names to preserve case
|
||||
:param formatters: dictionary mapping field names to callables
|
||||
to format the values
|
||||
"""
|
||||
row = []
|
||||
|
||||
for field in fields:
|
||||
if field in formatters:
|
||||
row.append(formatters[field](item))
|
||||
else:
|
||||
if field in mixed_case_fields:
|
||||
field_name = field.replace(' ', '_')
|
||||
else:
|
||||
field_name = field.lower().replace(' ', '_')
|
||||
if not hasattr(item, field_name) and \
|
||||
(isinstance(item, dict) and field_name in item):
|
||||
data = item[field_name]
|
||||
else:
|
||||
data = getattr(item, field_name, '')
|
||||
if data is None:
|
||||
data = ''
|
||||
row.append(data)
|
||||
return tuple(row)
|
||||
|
||||
|
||||
def get_columns(data):
|
||||
"""
|
||||
Some row's might have variable count of columns, ensure that we have the
|
||||
same.
|
||||
|
||||
:param data: Results in [{}, {]}]
|
||||
"""
|
||||
columns = set()
|
||||
|
||||
def _seen(col):
|
||||
columns.add(str(col))
|
||||
|
||||
six.moves.map(lambda item: six.moves.map(_seen,
|
||||
list(six.iterkeys(item))), data)
|
||||
return list(columns)
|
||||
|
||||
|
||||
@removals.removed_kwarg('all_tenants', removal_version='1.3.0')
|
||||
@removals.removed_kwarg('edit_managed', removal_version='1.3.0')
|
||||
def get_session(auth_url, endpoint, domain_id, domain_name, project_id,
|
||||
project_name, project_domain_name, project_domain_id, username,
|
||||
user_id, password, user_domain_id, user_domain_name, token,
|
||||
insecure, cacert, all_tenants=False, edit_managed=False):
|
||||
# NOTE: all_tenants and edit_managed are here for backwards compat
|
||||
# reasons, do not add additional modifiers here.
|
||||
|
||||
session = ks_session.Session()
|
||||
|
||||
# Build + Attach Authentication Plugin
|
||||
auth_args = {
|
||||
'auth_url': auth_url,
|
||||
'domain_id': domain_id,
|
||||
'domain_name': domain_name,
|
||||
'project_id': project_id,
|
||||
'project_name': project_name,
|
||||
'project_domain_name': project_domain_name,
|
||||
'project_domain_id': project_domain_id,
|
||||
}
|
||||
|
||||
if token and endpoint:
|
||||
session.auth = token_endpoint.Token(endpoint, token)
|
||||
|
||||
elif token:
|
||||
auth_args.update({
|
||||
'token': token
|
||||
})
|
||||
session.auth = generic.Token(**auth_args)
|
||||
|
||||
else:
|
||||
auth_args.update({
|
||||
'username': username,
|
||||
'user_id': user_id,
|
||||
'password': password,
|
||||
'user_domain_id': user_domain_id,
|
||||
'user_domain_name': user_domain_name,
|
||||
})
|
||||
session.auth = generic.Password(**auth_args)
|
||||
|
||||
# SSL/TLS Server Cert Verification
|
||||
if insecure is True:
|
||||
session.verify = False
|
||||
else:
|
||||
session.verify = cacert
|
||||
|
||||
# NOTE: all_tenants and edit_managed are here for backwards compat
|
||||
# reasons, do not add additional modifiers here.
|
||||
session.all_tenants = all_tenants
|
||||
session.edit_managed = edit_managed
|
||||
|
||||
return session
|
||||
|
||||
|
||||
def find_resourceid_by_name_or_id(resource_client, name_or_id):
|
||||
"""Find resource id from its id or name."""
|
||||
try:
|
||||
# Try to return an uuid
|
||||
return str(uuid.UUID(name_or_id))
|
||||
except ValueError:
|
||||
# Not an uuid => assume it is resource name
|
||||
pass
|
||||
|
||||
resources = resource_client.list()
|
||||
candidate_ids = [r['id'] for r in resources if r.get('name') == name_or_id]
|
||||
if not candidate_ids:
|
||||
raise exceptions.ResourceNotFound(
|
||||
'Could not find resource with name "%s"' % name_or_id)
|
||||
elif len(candidate_ids) > 1:
|
||||
str_ids = ','.join(candidate_ids)
|
||||
raise exceptions.NoUniqueMatch(
|
||||
'Multiple resources with name "%s": %s' % (name_or_id, str_ids))
|
||||
return candidate_ids[0]
|
||||
|
||||
|
||||
class AdapterWithTimeout(adapter.Adapter):
|
||||
"""adapter.Adapter wraps around a Session.
|
||||
|
||||
The user can pass a timeout keyword that will apply only to
|
||||
the Designate Client, in order:
|
||||
|
||||
- timeout keyword passed to ``request()``
|
||||
- timeout keyword passed to ``AdapterWithTimeout()``
|
||||
- timeout attribute on keystone session
|
||||
"""
|
||||
def __init__(self, *args, **kw):
|
||||
self.timeout = kw.pop('timeout', None)
|
||||
super(self.__class__, self).__init__(*args, **kw)
|
||||
|
||||
def request(self, *args, **kwargs):
|
||||
if self.timeout is not None:
|
||||
kwargs.setdefault('timeout', self.timeout)
|
||||
|
||||
return super(AdapterWithTimeout, self).request(*args, **kwargs)
|
@@ -1,161 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 debtcollector import removals
|
||||
from stevedore import extension
|
||||
|
||||
from designateclient import exceptions
|
||||
from designateclient import utils
|
||||
from designateclient import version
|
||||
|
||||
|
||||
@removals.removed_class(
|
||||
'designateclient.v1.Client',
|
||||
replacement='designateclient.v2.client.Client',
|
||||
message='Designate v1 API is being retired, and the v1 Client class will '
|
||||
'stop functioning. Please update code to the '
|
||||
'designateclient.v2.client.Client class. The API is deprecated',
|
||||
version='2.2.0',
|
||||
removal_version='?',
|
||||
stacklevel=3)
|
||||
class Client(object):
|
||||
"""Client for the Designate v1 API"""
|
||||
|
||||
def __init__(self, endpoint=None, username=None, user_id=None,
|
||||
user_domain_id=None, user_domain_name=None, password=None,
|
||||
tenant_name=None, tenant_id=None, domain_name=None,
|
||||
domain_id=None, project_name=None,
|
||||
project_id=None, project_domain_name=None,
|
||||
project_domain_id=None, auth_url=None, token=None,
|
||||
endpoint_type='publicURL', region_name=None,
|
||||
service_type='dns', insecure=False, session=None,
|
||||
cacert=None, all_tenants=None, edit_managed=None,
|
||||
timeout=None):
|
||||
"""
|
||||
:param endpoint: Endpoint URL
|
||||
:param token: A token instead of username / password
|
||||
:param insecure: Allow "insecure" HTTPS requests
|
||||
"""
|
||||
|
||||
if endpoint:
|
||||
endpoint = endpoint.rstrip('/')
|
||||
if not endpoint.endswith('v1'):
|
||||
endpoint = "%s/v1" % endpoint
|
||||
|
||||
# Compatibility code to mimic the old behaviour of the client
|
||||
if session is None:
|
||||
session = utils.get_session(
|
||||
auth_url=auth_url,
|
||||
endpoint=endpoint,
|
||||
domain_id=domain_id,
|
||||
domain_name=domain_name,
|
||||
project_id=project_id or tenant_id,
|
||||
project_name=project_name or tenant_name,
|
||||
project_domain_name=project_domain_name,
|
||||
project_domain_id=project_domain_id,
|
||||
username=username,
|
||||
user_id=user_id,
|
||||
password=password,
|
||||
user_domain_id=user_domain_id,
|
||||
user_domain_name=user_domain_name,
|
||||
token=token,
|
||||
insecure=insecure,
|
||||
cacert=cacert,
|
||||
)
|
||||
|
||||
# NOTE: all_tenants and edit_managed are pulled from the session for
|
||||
# backwards compat reasons, do not pull additional modifiers from
|
||||
# here. Once removed, the kwargs above should default to False.
|
||||
if all_tenants is None:
|
||||
self.all_tenants = getattr(session, 'all_tenants', False)
|
||||
else:
|
||||
self.all_tenants = all_tenants
|
||||
|
||||
if edit_managed is None:
|
||||
self.edit_managed = getattr(session, 'edit_managed', False)
|
||||
else:
|
||||
self.edit_managed = edit_managed
|
||||
|
||||
# Since we have to behave nicely like a legacy client/bindings we use
|
||||
# an adapter around the session to not modify it's state.
|
||||
interface = endpoint_type.rstrip('URL')
|
||||
|
||||
self.session = utils.AdapterWithTimeout(
|
||||
session,
|
||||
auth=session.auth,
|
||||
endpoint_override=endpoint,
|
||||
region_name=region_name,
|
||||
service_type=service_type,
|
||||
interface=interface,
|
||||
user_agent='python-designateclient-%s' % version.version_info,
|
||||
version='1',
|
||||
timeout=timeout,
|
||||
)
|
||||
|
||||
def _load_controller(ext):
|
||||
controller = ext.plugin(client=self)
|
||||
setattr(self, ext.name, controller)
|
||||
|
||||
# Load all controllers
|
||||
mgr = extension.ExtensionManager('designateclient.v1.controllers')
|
||||
mgr.map(_load_controller)
|
||||
|
||||
def wrap_api_call(self, func, *args, **kw):
|
||||
"""
|
||||
Wrap a self.<rest function> with exception handling
|
||||
|
||||
:param func: The function to wrap
|
||||
"""
|
||||
kw['raise_exc'] = False
|
||||
kw.setdefault('headers', {})
|
||||
kw['headers'].setdefault('Content-Type', 'application/json')
|
||||
if self.all_tenants:
|
||||
kw['headers'].update({'X-Auth-All-Projects': 'true'})
|
||||
if self.edit_managed:
|
||||
kw['headers'].update({'X-Designate-Edit-Managed-Records': 'true'})
|
||||
|
||||
# Trigger the request
|
||||
response = func(*args, **kw)
|
||||
|
||||
# Decode is response, if possible
|
||||
try:
|
||||
response_payload = response.json()
|
||||
except ValueError:
|
||||
response_payload = {}
|
||||
|
||||
if response.status_code == 400:
|
||||
raise exceptions.BadRequest(**response_payload)
|
||||
elif response.status_code in (401, 403, 413):
|
||||
raise exceptions.Forbidden(**response_payload)
|
||||
elif response.status_code == 404:
|
||||
raise exceptions.NotFound(**response_payload)
|
||||
elif response.status_code == 409:
|
||||
raise exceptions.Conflict(**response_payload)
|
||||
elif response.status_code >= 500:
|
||||
raise exceptions.Unknown(**response_payload)
|
||||
else:
|
||||
return response
|
||||
|
||||
def get(self, path, **kw):
|
||||
return self.wrap_api_call(self.session.get, path, **kw)
|
||||
|
||||
def post(self, path, **kw):
|
||||
return self.wrap_api_call(self.session.post, path, **kw)
|
||||
|
||||
def put(self, path, **kw):
|
||||
return self.wrap_api_call(self.session.put, path, **kw)
|
||||
|
||||
def delete(self, path, **kw):
|
||||
return self.wrap_api_call(self.session.delete, path, **kw)
|
@@ -1,27 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 designateclient import client
|
||||
|
||||
|
||||
class DiagnosticsController(client.Controller):
|
||||
def ping(self, service, host):
|
||||
"""
|
||||
Ping a service on a given host
|
||||
"""
|
||||
response = self.client.get('/diagnostics/ping/%s/%s' %
|
||||
(service, host))
|
||||
|
||||
return response.json()
|
@@ -1,92 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 designateclient import client
|
||||
from designateclient import utils
|
||||
from designateclient import warlock
|
||||
|
||||
|
||||
Domain = warlock.model_factory(utils.load_schema('v1', 'domain'))
|
||||
Server = warlock.model_factory(utils.load_schema('v1', 'server'))
|
||||
|
||||
|
||||
class DomainsController(client.CrudController):
|
||||
def list(self):
|
||||
"""
|
||||
Retrieve a list of domains
|
||||
|
||||
:returns: A list of :class:`Domain`
|
||||
"""
|
||||
response = self.client.get('/domains')
|
||||
|
||||
return [Domain(i) for i in response.json()['domains']]
|
||||
|
||||
def get(self, domain_id):
|
||||
"""
|
||||
Retrieve a domain
|
||||
|
||||
:param domain_id: Domain Identifier
|
||||
:returns: :class:`Domain`
|
||||
"""
|
||||
response = self.client.get('/domains/%s' % domain_id)
|
||||
|
||||
return Domain(response.json())
|
||||
|
||||
def create(self, domain):
|
||||
"""
|
||||
Create a domain
|
||||
|
||||
:param domain: A :class:`Domain` to create
|
||||
:returns: :class:`Domain`
|
||||
"""
|
||||
response = self.client.post('/domains', data=json.dumps(domain))
|
||||
|
||||
return Domain(response.json())
|
||||
|
||||
def update(self, domain):
|
||||
"""
|
||||
Update a domain
|
||||
|
||||
:param domain: A :class:`Domain` to update
|
||||
:returns: :class:`Domain`
|
||||
"""
|
||||
response = self.client.put('/domains/%s' % domain.id,
|
||||
data=json.dumps(domain.changes))
|
||||
|
||||
return Domain(response.json())
|
||||
|
||||
def delete(self, domain):
|
||||
"""
|
||||
Delete a domain
|
||||
|
||||
:param domain: A :class:`Domain`, or Domain Identifier to delete
|
||||
"""
|
||||
if isinstance(domain, Domain):
|
||||
self.client.delete('/domains/%s' % domain.id)
|
||||
else:
|
||||
self.client.delete('/domains/%s' % domain)
|
||||
|
||||
def list_domain_servers(self, domain_id):
|
||||
"""
|
||||
Retrieve the list of nameservers for a domain
|
||||
|
||||
:param domain_id: Domain Identifier
|
||||
:returns: A list of :class:`Server`
|
||||
"""
|
||||
response = self.client.get('/domains/%s/servers' % domain_id)
|
||||
|
||||
return [Server(i) for i in response.json()['servers']]
|
@@ -1,38 +0,0 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 designateclient import client
|
||||
|
||||
|
||||
class QuotasController(client.Controller):
|
||||
def get(self, tenant_id):
|
||||
"""
|
||||
Ping a service on a given host
|
||||
"""
|
||||
response = self.client.get('/quotas/%s' % tenant_id)
|
||||
|
||||
return response.json()
|
||||
|
||||
def update(self, tenant_id, values):
|
||||
response = self.client.put('/quotas/%s' % tenant_id,
|
||||
data=json.dumps(values))
|
||||
return response.json()
|
||||
|
||||
def reset(self, tenant_id):
|
||||
response = self.client.delete('/quotas/%s' % tenant_id)
|
||||
|
||||
return response
|
@@ -1,115 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 designateclient import client
|
||||
from designateclient import utils
|
||||
from designateclient.v1.domains import Domain
|
||||
from designateclient import warlock
|
||||
|
||||
|
||||
Record = warlock.model_factory(utils.load_schema('v1', 'record'))
|
||||
|
||||
|
||||
class RecordsController(client.CrudController):
|
||||
def list(self, domain):
|
||||
"""
|
||||
Retrieve a list of records
|
||||
|
||||
:param domain: :class:`Domain` or Domain Identifier
|
||||
:returns: A list of :class:`Record`
|
||||
"""
|
||||
domain_id = domain.id if isinstance(domain, Domain) else domain
|
||||
|
||||
response = self.client.get('/domains/%(domain_id)s/records' % {
|
||||
'domain_id': domain_id
|
||||
})
|
||||
|
||||
return [Record(i) for i in response.json()['records']]
|
||||
|
||||
def get(self, domain, record_id):
|
||||
"""
|
||||
Retrieve a record
|
||||
|
||||
:param domain: :class:`Domain` or Domain Identifier
|
||||
:param record_id: Record Identifier
|
||||
:returns: :class:`Record`
|
||||
"""
|
||||
domain_id = domain.id if isinstance(domain, Domain) else domain
|
||||
|
||||
uri = '/domains/%(domain_id)s/records/%(record_id)s' % {
|
||||
'domain_id': domain_id,
|
||||
'record_id': record_id
|
||||
}
|
||||
|
||||
response = self.client.get(uri)
|
||||
|
||||
return Record(response.json())
|
||||
|
||||
def create(self, domain, record):
|
||||
"""
|
||||
Create a record
|
||||
|
||||
:param domain: :class:`Domain` or Domain Identifier
|
||||
:param record: A :class:`Record` to create
|
||||
:returns: :class:`Record`
|
||||
"""
|
||||
domain_id = domain.id if isinstance(domain, Domain) else domain
|
||||
|
||||
uri = '/domains/%(domain_id)s/records' % {
|
||||
'domain_id': domain_id
|
||||
}
|
||||
|
||||
response = self.client.post(uri, data=json.dumps(record))
|
||||
|
||||
return Record(response.json())
|
||||
|
||||
def update(self, domain, record):
|
||||
"""
|
||||
Update a record
|
||||
|
||||
:param domain: :class:`Domain` or Domain Identifier
|
||||
:param record: A :class:`Record` to update
|
||||
:returns: :class:`Record`
|
||||
"""
|
||||
domain_id = domain.id if isinstance(domain, Domain) else domain
|
||||
|
||||
uri = '/domains/%(domain_id)s/records/%(record_id)s' % {
|
||||
'domain_id': domain_id,
|
||||
'record_id': record.id
|
||||
}
|
||||
|
||||
response = self.client.put(uri, data=json.dumps(record.changes))
|
||||
|
||||
return Record(response.json())
|
||||
|
||||
def delete(self, domain, record):
|
||||
"""
|
||||
Delete a record
|
||||
|
||||
:param domain: :class:`Domain` or Domain Identifier
|
||||
:param record: A :class:`Record`, or Record Identifier to delete
|
||||
"""
|
||||
domain_id = domain.id if isinstance(domain, Domain) else domain
|
||||
record_id = record.id if isinstance(record, Record) else record
|
||||
|
||||
uri = '/domains/%(domain_id)s/records/%(record_id)s' % {
|
||||
'domain_id': domain_id,
|
||||
'record_id': record_id
|
||||
}
|
||||
|
||||
self.client.delete(uri)
|
@@ -1,67 +0,0 @@
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P. All Rights Reserved.
|
||||
#
|
||||
# Author: Patrick Galbraith <patg@patg.net>
|
||||
#
|
||||
# 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 designateclient import client
|
||||
|
||||
|
||||
class ReportsController(client.Controller):
|
||||
def count_all(self):
|
||||
"""
|
||||
Domain, Records and tenant total count
|
||||
"""
|
||||
response = self.client.get('/reports/counts')
|
||||
|
||||
return response.json()
|
||||
|
||||
def count_domains(self):
|
||||
"""
|
||||
Domain total count
|
||||
"""
|
||||
response = self.client.get('/reports/counts/domains')
|
||||
|
||||
return response.json()
|
||||
|
||||
def count_tenants(self):
|
||||
"""
|
||||
Tenant total count
|
||||
"""
|
||||
response = self.client.get('/reports/counts/tenants')
|
||||
|
||||
return response.json()
|
||||
|
||||
def count_records(self):
|
||||
"""
|
||||
Record total count
|
||||
"""
|
||||
response = self.client.get('/reports/counts/records')
|
||||
|
||||
return response.json()
|
||||
|
||||
def tenants_all(self):
|
||||
"""
|
||||
Per tenant count
|
||||
"""
|
||||
response = self.client.get('/reports/tenants')
|
||||
|
||||
return response.json()['tenants']
|
||||
|
||||
def tenant_domains(self, other_tenant_id):
|
||||
"""
|
||||
Tenant's domain count
|
||||
"""
|
||||
response = self.client.get('/reports/tenants/%s' %
|
||||
other_tenant_id)
|
||||
|
||||
return [{'domain': d} for d in response.json()['domains']]
|
@@ -1,81 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 designateclient import client
|
||||
from designateclient import utils
|
||||
from designateclient import warlock
|
||||
|
||||
|
||||
Server = warlock.model_factory(utils.load_schema('v1', 'server'))
|
||||
|
||||
|
||||
class ServersController(client.CrudController):
|
||||
def list(self):
|
||||
"""
|
||||
Retrieve a list of servers
|
||||
|
||||
:returns: A list of :class:`Server`
|
||||
"""
|
||||
response = self.client.get('/servers')
|
||||
|
||||
return [Server(i) for i in response.json()['servers']]
|
||||
|
||||
def get(self, server_id):
|
||||
"""
|
||||
Retrieve a server
|
||||
|
||||
:param server_id: Server Identifier
|
||||
:returns: :class:`Server`
|
||||
"""
|
||||
response = self.client.get('/servers/%s' % server_id)
|
||||
|
||||
return Server(response.json())
|
||||
|
||||
def create(self, server):
|
||||
"""
|
||||
Create a server
|
||||
|
||||
:param server: A :class:`Server` to create
|
||||
:returns: :class:`Server`
|
||||
"""
|
||||
response = self.client.post('/servers', data=json.dumps(server))
|
||||
|
||||
return Server(response.json())
|
||||
|
||||
def update(self, server):
|
||||
"""
|
||||
Update a server
|
||||
|
||||
:param server: A :class:`Server` to update
|
||||
:returns: :class:`Server`
|
||||
"""
|
||||
response = self.client.put('/servers/%s' % server.id,
|
||||
data=json.dumps(server.changes))
|
||||
|
||||
return Server(response.json())
|
||||
|
||||
def delete(self, server):
|
||||
"""
|
||||
Delete a server
|
||||
|
||||
:param server: A :class:`Server`, or Server Identifier to delete
|
||||
"""
|
||||
if isinstance(server, Server):
|
||||
self.client.delete('/servers/%s' % server.id)
|
||||
else:
|
||||
self.client.delete('/servers/%s' % server)
|
@@ -1,37 +0,0 @@
|
||||
# Copyright 2012 Managed I.T.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@managedit.ie>
|
||||
#
|
||||
# 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 designateclient import client
|
||||
|
||||
|
||||
class SyncController(client.Controller):
|
||||
def sync_all(self):
|
||||
"""
|
||||
Sync Everything
|
||||
"""
|
||||
self.client.post('/domains/sync')
|
||||
|
||||
def sync_domain(self, domain_id):
|
||||
"""
|
||||
Sync Single Domain
|
||||
"""
|
||||
self.client.post('/domains/%s/sync' % domain_id)
|
||||
|
||||
def sync_record(self, domain_id, record_id):
|
||||
"""
|
||||
Sync Single Record
|
||||
"""
|
||||
self.client.post('/domains/%s/records/%s/sync' %
|
||||
(domain_id, record_id))
|
@@ -1,24 +0,0 @@
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Kiall Mac Innes <kiall@hp.com>
|
||||
#
|
||||
# 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 designateclient import client
|
||||
|
||||
|
||||
class TouchController(client.Controller):
|
||||
def domain(self, domain_id):
|
||||
"""
|
||||
Touch a single Domain
|
||||
"""
|
||||
self.client.post('/domains/%s/touch' % domain_id)
|
@@ -1,43 +0,0 @@
|
||||
# Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||
#
|
||||
# Author: Graham Hayes <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 designateclient import client
|
||||
from designateclient.v2.utils import parse_query_from_url
|
||||
|
||||
|
||||
class DesignateList(list):
|
||||
|
||||
next_link_criterion = {}
|
||||
next_page = False
|
||||
|
||||
|
||||
class V2Controller(client.Controller):
|
||||
|
||||
def _get(self, url, response_key=None, **kwargs):
|
||||
resp, body = self.client.session.get(url, **kwargs)
|
||||
|
||||
if response_key is not None:
|
||||
data = DesignateList()
|
||||
data.extend(body[response_key])
|
||||
|
||||
if 'next' in body.get('links', {}):
|
||||
data.next_page = True
|
||||
data.next_link_criterion = parse_query_from_url(
|
||||
body['links']['next'])
|
||||
|
||||
return data
|
||||
|
||||
return body
|
@@ -1,48 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 designateclient.v2.base import V2Controller
|
||||
|
||||
|
||||
class BlacklistController(V2Controller):
|
||||
def create(self, pattern, description=None):
|
||||
data = {
|
||||
'pattern': pattern,
|
||||
}
|
||||
|
||||
if description is not None:
|
||||
data['description'] = description
|
||||
|
||||
return self._post('/blacklists', data=data)
|
||||
|
||||
def list(self, criterion=None, marker=None, limit=None):
|
||||
url = self.build_url('/blacklists', criterion, marker, limit)
|
||||
|
||||
return self._get(url, response_key="blacklists")
|
||||
|
||||
def get(self, blacklist_id):
|
||||
url = '/blacklists/%s' % blacklist_id
|
||||
|
||||
return self._get(url)
|
||||
|
||||
def update(self, blacklist_id, values):
|
||||
url = '/blacklists/%s' % blacklist_id
|
||||
|
||||
return self._patch(url, data=values)
|
||||
|
||||
def delete(self, blacklist_id):
|
||||
url = '/blacklists/%s' % blacklist_id
|
||||
|
||||
return self._delete(url)
|
@@ -1,155 +0,0 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 logging
|
||||
|
||||
from osc_lib.command import command
|
||||
import six
|
||||
|
||||
from designateclient import utils
|
||||
from designateclient.v2.cli import common
|
||||
from designateclient.v2.utils import get_all
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _format_blacklist(blacklist):
|
||||
# Remove unneeded fields for display output formatting
|
||||
blacklist.pop('links', None)
|
||||
|
||||
|
||||
class ListBlacklistsCommand(command.Lister):
|
||||
"""List blacklists"""
|
||||
|
||||
columns = ['id', 'pattern', 'description']
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListBlacklistsCommand, self).get_parser(prog_name)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
cols = self.columns
|
||||
data = get_all(client.blacklists.list)
|
||||
return cols, (utils.get_item_properties(s, cols) for s in data)
|
||||
|
||||
|
||||
class ShowBlacklistCommand(command.ShowOne):
|
||||
"""Show blacklist details"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowBlacklistCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Blacklist ID")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
data = client.blacklists.get(parsed_args.id)
|
||||
_format_blacklist(data)
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class CreateBlacklistCommand(command.ShowOne):
|
||||
"""Create new blacklist"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateBlacklistCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('--pattern', help="Blacklist pattern",
|
||||
required=True)
|
||||
parser.add_argument('--description', help="Description")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.blacklists.create(
|
||||
parsed_args.pattern, parsed_args.description)
|
||||
|
||||
_format_blacklist(data)
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class SetBlacklistCommand(command.ShowOne):
|
||||
"""Set blacklist properties"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(SetBlacklistCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Blacklist ID")
|
||||
parser.add_argument('--pattern', help="Blacklist pattern")
|
||||
|
||||
description_group = parser.add_mutually_exclusive_group()
|
||||
description_group.add_argument('--description', help="Description")
|
||||
description_group.add_argument('--no-description', action='store_true')
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
data = {}
|
||||
|
||||
if parsed_args.pattern:
|
||||
data['pattern'] = parsed_args.pattern
|
||||
|
||||
if parsed_args.no_description:
|
||||
data['description'] = None
|
||||
elif parsed_args.description:
|
||||
data['description'] = parsed_args.description
|
||||
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
updated = client.blacklists.update(parsed_args.id, data)
|
||||
|
||||
_format_blacklist(updated)
|
||||
return six.moves.zip(*sorted(six.iteritems(updated)))
|
||||
|
||||
|
||||
class DeleteBlacklistCommand(command.Command):
|
||||
"""Delete blacklist"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteBlacklistCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Blacklist ID")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
client.blacklists.delete(parsed_args.id)
|
||||
|
||||
LOG.info('Blacklist %s was deleted', parsed_args.id)
|
@@ -1,74 +0,0 @@
|
||||
# Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||
#
|
||||
# Author: Graham Hayes <endre.karlson@hp.com>
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
def add_all_projects_option(parser):
|
||||
parser.add_argument(
|
||||
'--all-projects',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help='Show results from all projects. Default: False'
|
||||
)
|
||||
|
||||
|
||||
def add_edit_managed_option(parser):
|
||||
parser.add_argument(
|
||||
'--edit-managed',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help='Edit resources marked as managed. Default: False'
|
||||
)
|
||||
|
||||
|
||||
def add_sudo_project_id_option(parser):
|
||||
parser.add_argument(
|
||||
'--sudo-project-id',
|
||||
default=None,
|
||||
help='Project ID to impersonate for this command. Default: None'
|
||||
)
|
||||
|
||||
|
||||
def add_all_common_options(parser):
|
||||
add_all_projects_option(parser)
|
||||
add_edit_managed_option(parser)
|
||||
add_sudo_project_id_option(parser)
|
||||
|
||||
|
||||
def set_all_projects(client, value):
|
||||
client.session.all_projects = value
|
||||
|
||||
|
||||
def set_sudo_project_id(client, value):
|
||||
client.session.sudo_project_id = value
|
||||
|
||||
|
||||
def set_edit_managed(client, value):
|
||||
client.session.edit_managed = value
|
||||
|
||||
|
||||
def set_all_common_headers(client, parsed_args):
|
||||
|
||||
if parsed_args.all_projects is not None and \
|
||||
isinstance(parsed_args.all_projects, bool):
|
||||
set_all_projects(client, parsed_args.all_projects)
|
||||
|
||||
if parsed_args.edit_managed is not None and \
|
||||
isinstance(parsed_args.edit_managed, bool):
|
||||
set_edit_managed(client, parsed_args.edit_managed)
|
||||
|
||||
if parsed_args.sudo_project_id is not None and \
|
||||
isinstance(parsed_args.sudo_project_id, str):
|
||||
set_sudo_project_id(client, parsed_args.sudo_project_id)
|
@@ -1,133 +0,0 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 itertools
|
||||
import logging
|
||||
|
||||
from cliff import command
|
||||
from cliff import show
|
||||
import six
|
||||
|
||||
from designateclient.v2.cli import common
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
DNS_QUOTAS = {
|
||||
"api_export_size": "api-export-size",
|
||||
"recordset_records": "recordset-records",
|
||||
"zone_records": "zone-records",
|
||||
"zone_recordsets": "zone-recordsets",
|
||||
"zones": "zones"
|
||||
}
|
||||
|
||||
|
||||
class ListQuotasCommand(show.ShowOne):
|
||||
"""List quotas"""
|
||||
|
||||
# columns = ['resource', 'hard_limit']
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListQuotasCommand, self).get_parser(prog_name)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
parser.add_argument(
|
||||
'--project-id',
|
||||
help="Project ID Default: current project")
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
proj_id = parsed_args.project_id or client.session.get_project_id()
|
||||
|
||||
if parsed_args.project_id != client.session.get_project_id():
|
||||
common.set_all_projects(client, True)
|
||||
|
||||
data = client.quotas.list(proj_id)
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class SetQuotasCommand(show.ShowOne):
|
||||
"""Set blacklist properties"""
|
||||
|
||||
def _build_options_list(self):
|
||||
return itertools.chain(DNS_QUOTAS.items())
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(SetQuotasCommand, self).get_parser(prog_name)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
parser.add_argument('--project-id', help="Project ID")
|
||||
for k, v in self._build_options_list():
|
||||
parser.add_argument(
|
||||
'--%s' % v,
|
||||
metavar='<%s>' % v,
|
||||
dest=k,
|
||||
type=int,
|
||||
help='New value for the %s quota' % v,
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
quotas = {}
|
||||
for k, v in DNS_QUOTAS.items():
|
||||
value = getattr(parsed_args, k, None)
|
||||
if value is not None:
|
||||
quotas[k] = value
|
||||
|
||||
proj_id = parsed_args.project_id or client.session.get_project_id()
|
||||
|
||||
if parsed_args.project_id != client.session.get_project_id():
|
||||
common.set_all_projects(client, True)
|
||||
|
||||
updated = client.quotas.update(proj_id, quotas)
|
||||
|
||||
return six.moves.zip(*sorted(six.iteritems(updated)))
|
||||
|
||||
|
||||
class ResetQuotasCommand(command.Command):
|
||||
"""Delete blacklist"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ResetQuotasCommand, self).get_parser(prog_name)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
parser.add_argument('--project-id', help="Project ID")
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
proj_id = parsed_args.project_id or client.session.get_project_id()
|
||||
|
||||
if parsed_args.project_id != client.session.get_project_id():
|
||||
common.set_all_projects(client, True)
|
||||
|
||||
client.quotas.reset(proj_id)
|
||||
|
||||
LOG.info('Quota for project %s was reset', parsed_args.project_id)
|
@@ -1,246 +0,0 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 logging
|
||||
|
||||
from osc_lib.command import command
|
||||
import six
|
||||
|
||||
from designateclient import utils
|
||||
from designateclient.v2.cli import common
|
||||
from designateclient.v2.utils import get_all
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _format_recordset(recordset):
|
||||
# Remove unneeded fields for display output formatting
|
||||
recordset['records'] = "\n".join(recordset['records'])
|
||||
recordset.pop('links', None)
|
||||
return recordset
|
||||
|
||||
|
||||
def _has_project_id(data):
|
||||
if len(data) < 1:
|
||||
return False
|
||||
if 'project_id' in data[0]:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class ListRecordSetsCommand(command.Lister):
|
||||
"""List recordsets"""
|
||||
|
||||
columns = ['id', 'name', 'type', 'records', 'status', 'action']
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListRecordSetsCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('--name', help="RecordSet Name", required=False)
|
||||
parser.add_argument('--type', help="RecordSet Type", required=False)
|
||||
parser.add_argument('--data', help="RecordSet Record Data",
|
||||
required=False)
|
||||
parser.add_argument('--ttl', help="Time To Live (Seconds)",
|
||||
required=False)
|
||||
parser.add_argument('--description', help="Description",
|
||||
required=False)
|
||||
parser.add_argument('--status', help="RecordSet Status",
|
||||
required=False)
|
||||
parser.add_argument('--action', help="RecordSet Action",
|
||||
required=False)
|
||||
|
||||
parser.add_argument('zone_id', help="Zone ID. To list all"
|
||||
" recordsets specify 'all'")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
criterion = {}
|
||||
if parsed_args.type is not None:
|
||||
criterion["type"] = parsed_args.type
|
||||
|
||||
if parsed_args.name is not None:
|
||||
criterion["name"] = parsed_args.name
|
||||
|
||||
if parsed_args.data is not None:
|
||||
criterion["data"] = parsed_args.data
|
||||
|
||||
if parsed_args.ttl is not None:
|
||||
criterion["ttl"] = parsed_args.ttl
|
||||
|
||||
if parsed_args.description is not None:
|
||||
criterion["description"] = parsed_args.description
|
||||
|
||||
if parsed_args.status is not None:
|
||||
criterion["status"] = parsed_args.status
|
||||
|
||||
if parsed_args.action is not None:
|
||||
criterion["action"] = parsed_args.action
|
||||
|
||||
cols = self.columns
|
||||
|
||||
if parsed_args.zone_id == 'all':
|
||||
data = get_all(client.recordsets.list_all_zones,
|
||||
criterion=criterion)
|
||||
cols.insert(2, 'zone_name')
|
||||
else:
|
||||
data = get_all(client.recordsets.list, args=[parsed_args.zone_id],
|
||||
criterion=criterion)
|
||||
|
||||
if client.session.all_projects and _has_project_id(data):
|
||||
cols.insert(1, 'project_id')
|
||||
|
||||
for i, rs in enumerate(data):
|
||||
data[i] = _format_recordset(rs)
|
||||
|
||||
return cols, (utils.get_item_properties(s, cols) for s in data)
|
||||
|
||||
|
||||
class ShowRecordSetCommand(command.ShowOne):
|
||||
"""Show recordset details"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowRecordSetCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('zone_id', help="Zone ID")
|
||||
parser.add_argument('id', help="RecordSet ID")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
data = client.recordsets.get(parsed_args.zone_id, parsed_args.id)
|
||||
|
||||
_format_recordset(data)
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class CreateRecordSetCommand(command.ShowOne):
|
||||
"""Create new recordset"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateRecordSetCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('zone_id', help="Zone ID")
|
||||
parser.add_argument('name', help="RecordSet Name")
|
||||
parser.add_argument('--records', help="RecordSet Records",
|
||||
nargs='+', required=True)
|
||||
parser.add_argument('--type', help="RecordSet Type", required=True)
|
||||
parser.add_argument('--ttl', type=int, help="Time To Live (Seconds)")
|
||||
parser.add_argument('--description', help="Description")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.recordsets.create(
|
||||
parsed_args.zone_id,
|
||||
parsed_args.name,
|
||||
parsed_args.type,
|
||||
parsed_args.records,
|
||||
description=parsed_args.description,
|
||||
ttl=parsed_args.ttl)
|
||||
|
||||
_format_recordset(data)
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class SetRecordSetCommand(command.ShowOne):
|
||||
"""Set recordset properties"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(SetRecordSetCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('zone_id', help="Zone ID")
|
||||
parser.add_argument('id', help="RecordSet ID")
|
||||
parser.add_argument('--records', help="Records", nargs='+')
|
||||
|
||||
description_group = parser.add_mutually_exclusive_group()
|
||||
description_group.add_argument('--description', help="Description")
|
||||
description_group.add_argument('--no-description', action='store_true')
|
||||
|
||||
ttl_group = parser.add_mutually_exclusive_group()
|
||||
ttl_group.add_argument('--ttl', type=int, help="TTL")
|
||||
ttl_group.add_argument('--no-ttl', action='store_true')
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
data = {}
|
||||
|
||||
if parsed_args.no_description:
|
||||
data['description'] = None
|
||||
elif parsed_args.description:
|
||||
data['description'] = parsed_args.description
|
||||
|
||||
if parsed_args.no_ttl:
|
||||
data['ttl'] = None
|
||||
elif parsed_args.ttl:
|
||||
data['ttl'] = parsed_args.ttl
|
||||
|
||||
if parsed_args.records:
|
||||
data['records'] = parsed_args.records
|
||||
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
updated = client.recordsets.update(
|
||||
parsed_args.zone_id,
|
||||
parsed_args.id,
|
||||
data)
|
||||
|
||||
_format_recordset(updated)
|
||||
|
||||
return six.moves.zip(*sorted(six.iteritems(updated)))
|
||||
|
||||
|
||||
class DeleteRecordSetCommand(command.ShowOne):
|
||||
"""Delete recordset"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteRecordSetCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('zone_id', help="Zone ID")
|
||||
parser.add_argument('id', help="RecordSet ID")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
data = client.recordsets.delete(parsed_args.zone_id, parsed_args.id)
|
||||
|
||||
LOG.info('RecordSet %s was deleted', parsed_args.id)
|
||||
|
||||
_format_recordset(data)
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
@@ -1,142 +0,0 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 logging
|
||||
|
||||
from osc_lib.command import command
|
||||
import six
|
||||
|
||||
from designateclient import utils
|
||||
from designateclient.v2.cli import common
|
||||
from designateclient.v2.utils import get_all
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _format_floatingip(fip):
|
||||
# Remove unneeded fields for display output formatting
|
||||
fip.pop('links', None)
|
||||
|
||||
|
||||
class ListFloatingIPCommand(command.Lister):
|
||||
"""List floatingip ptr records"""
|
||||
|
||||
columns = ['id', 'ptrdname', 'description', 'ttl']
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListFloatingIPCommand, self).get_parser(prog_name)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
cols = self.columns
|
||||
data = get_all(client.floatingips.list)
|
||||
return cols, (utils.get_item_properties(s, cols) for s in data)
|
||||
|
||||
|
||||
class ShowFloatingIPCommand(command.ShowOne):
|
||||
"""Show floatingip ptr record details"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowFloatingIPCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('floatingip_id', help="Floating IP ID in format "
|
||||
"region:floatingip_id")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
data = client.floatingips.get(parsed_args.floatingip_id)
|
||||
_format_floatingip(data)
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class SetFloatingIPCommand(command.ShowOne):
|
||||
"""Set floatingip ptr record"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(SetFloatingIPCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('floatingip_id', help="Floating IP ID in format "
|
||||
"region:floatingip_id")
|
||||
parser.add_argument('ptrdname', help="PTRD Name")
|
||||
|
||||
description_group = parser.add_mutually_exclusive_group()
|
||||
description_group.add_argument('--description', help="Description")
|
||||
description_group.add_argument('--no-description', action='store_true')
|
||||
|
||||
ttl_group = parser.add_mutually_exclusive_group()
|
||||
ttl_group.add_argument('--ttl', type=int, help="TTL")
|
||||
ttl_group.add_argument('--no-ttl', action='store_true')
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
data = {}
|
||||
|
||||
if parsed_args.no_description:
|
||||
data['description'] = None
|
||||
elif parsed_args.description:
|
||||
data['description'] = parsed_args.description
|
||||
|
||||
if parsed_args.no_ttl:
|
||||
data['ttl'] = None
|
||||
elif parsed_args.ttl:
|
||||
data['ttl'] = parsed_args.ttl
|
||||
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
fip = client.floatingips.set(
|
||||
parsed_args.floatingip_id,
|
||||
parsed_args.ptrdname,
|
||||
parsed_args.description,
|
||||
parsed_args.ttl)
|
||||
|
||||
_format_floatingip(fip)
|
||||
return six.moves.zip(*sorted(six.iteritems(fip)))
|
||||
|
||||
|
||||
class UnsetFloatingIPCommand(command.Command):
|
||||
"""Unset floatingip ptr record"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(UnsetFloatingIPCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('floatingip_id', help="Floating IP ID in format "
|
||||
"region:floatingip_id")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
client.floatingips.unset(parsed_args.floatingip_id)
|
||||
LOG.info('FloatingIP PTR %s was unset', parsed_args.floatingip_id)
|
@@ -1,94 +0,0 @@
|
||||
# Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 logging
|
||||
|
||||
from osc_lib.command import command
|
||||
import six
|
||||
|
||||
from designateclient import utils
|
||||
from designateclient.v2.cli import common
|
||||
from designateclient.v2 import utils as v2_utils
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _format_status(status):
|
||||
status.pop("links", None)
|
||||
# Remove unneeded fields for display output formatting
|
||||
for k in ("capabilities", "stats"):
|
||||
status[k] = "\n".join(status[k]) if status[k] else "-"
|
||||
return status
|
||||
|
||||
|
||||
class ListServiceStatusesCommand(command.Lister):
|
||||
"""List service statuses"""
|
||||
|
||||
columns = ['id', 'hostname', 'service_name', 'status', 'stats',
|
||||
'capabilities']
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListServiceStatusesCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument("--hostname", help="Hostname", required=False)
|
||||
parser.add_argument("--service_name", help="Service Name",
|
||||
required=False)
|
||||
parser.add_argument("--status", help="Status", required=False)
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
cols = self.columns
|
||||
|
||||
criterion = {}
|
||||
for i in ["hostname", "service_name", "status"]:
|
||||
v = getattr(parsed_args, i)
|
||||
if v is not None:
|
||||
criterion[i] = v
|
||||
|
||||
data = v2_utils.get_all(client.service_statuses.list,
|
||||
criterion=criterion)
|
||||
|
||||
for i, s in enumerate(data):
|
||||
data[i] = _format_status(s)
|
||||
|
||||
return cols, (utils.get_item_properties(s, cols) for s in data)
|
||||
|
||||
|
||||
class ShowServiceStatusCommand(command.ShowOne):
|
||||
"""Show service status details"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowServiceStatusCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Service Status ID")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
data = client.service_statuses.get(parsed_args.id)
|
||||
|
||||
_format_status(data)
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
@@ -1,154 +0,0 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 logging
|
||||
|
||||
from osc_lib.command import command
|
||||
import six
|
||||
|
||||
from designateclient import utils
|
||||
from designateclient.v2.cli import common
|
||||
from designateclient.v2.utils import get_all
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _format_tld(tld):
|
||||
# Remove unneeded fields for display output formatting
|
||||
tld.pop('links', None)
|
||||
|
||||
|
||||
class ListTLDsCommand(command.Lister):
|
||||
"""List tlds"""
|
||||
|
||||
columns = ['id', 'name', 'description']
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListTLDsCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('--name', help="TLD NAME")
|
||||
|
||||
parser.add_argument('--description', help="TLD Description")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = get_all(client.tlds.list)
|
||||
|
||||
cols = self.columns
|
||||
return cols, (utils.get_item_properties(s, cols) for s in data)
|
||||
|
||||
|
||||
class ShowTLDCommand(command.ShowOne):
|
||||
"""Show tld details"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowTLDCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="TLD ID")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
data = client.tlds.get(parsed_args.id)
|
||||
_format_tld(data)
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class CreateTLDCommand(command.ShowOne):
|
||||
"""Create new tld"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateTLDCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('--name', help="TLD Name", required=True)
|
||||
parser.add_argument('--description', help="Description")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
data = client.tlds.create(parsed_args.name, parsed_args.description)
|
||||
_format_tld(data)
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class SetTLDCommand(command.ShowOne):
|
||||
"""Set tld properties"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(SetTLDCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="TLD ID")
|
||||
parser.add_argument('--name', help="TLD Name")
|
||||
description_group = parser.add_mutually_exclusive_group()
|
||||
description_group.add_argument('--description', help="Description")
|
||||
description_group.add_argument('--no-description', action='store_true')
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
data = {}
|
||||
|
||||
if parsed_args.name:
|
||||
data['name'] = parsed_args.name
|
||||
|
||||
if parsed_args.no_description:
|
||||
data['description'] = None
|
||||
elif parsed_args.description:
|
||||
data['description'] = parsed_args.description
|
||||
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.tlds.update(parsed_args.id, data)
|
||||
_format_tld(data)
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class DeleteTLDCommand(command.Command):
|
||||
"""Delete tld"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteTLDCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="TLD ID")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
client.tlds.delete(parsed_args.id)
|
||||
|
||||
LOG.info('TLD %s was deleted', parsed_args.id)
|
@@ -1,716 +0,0 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 logging
|
||||
|
||||
from osc_lib.command import command
|
||||
from osc_lib import exceptions as osc_exc
|
||||
import six
|
||||
|
||||
from designateclient import utils
|
||||
from designateclient.v2.cli import common
|
||||
from designateclient.v2.utils import get_all
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _format_zone(zone):
|
||||
zone.pop('links', None)
|
||||
zone['masters'] = ", ".join(zone['masters'])
|
||||
attrib = ''
|
||||
for attr in zone['attributes']:
|
||||
attrib += "%s:%s\n" % (attr, zone['attributes'][attr])
|
||||
zone['attributes'] = attrib
|
||||
|
||||
|
||||
def _format_zone_export_record(zone_export_record):
|
||||
zone_export_record.pop('links', None)
|
||||
|
||||
|
||||
def _format_zone_import_record(zone_import_record):
|
||||
zone_import_record.pop('links', None)
|
||||
|
||||
|
||||
class ListZonesCommand(command.Lister):
|
||||
"""List zones"""
|
||||
|
||||
columns = ['id', 'name', 'type', 'serial', 'status', 'action']
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListZonesCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('--name', help="Zone Name", required=False)
|
||||
parser.add_argument('--email', help="Zone Email", required=False)
|
||||
parser.add_argument('--type', help="Zone Type", required=False)
|
||||
parser.add_argument('--ttl', help="Time To Live (Seconds)",
|
||||
required=False)
|
||||
parser.add_argument('--description', help="Description",
|
||||
required=False)
|
||||
parser.add_argument('--status', help="Zone Status", required=False)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
criterion = {}
|
||||
if parsed_args.type is not None:
|
||||
criterion["type"] = parsed_args.type
|
||||
|
||||
if parsed_args.name is not None:
|
||||
criterion["name"] = parsed_args.name
|
||||
|
||||
if parsed_args.ttl is not None:
|
||||
criterion["ttl"] = parsed_args.ttl
|
||||
|
||||
if parsed_args.description is not None:
|
||||
criterion["description"] = parsed_args.description
|
||||
|
||||
if parsed_args.email is not None:
|
||||
criterion["email"] = parsed_args.email
|
||||
|
||||
if parsed_args.status is not None:
|
||||
criterion["status"] = parsed_args.status
|
||||
|
||||
data = get_all(client.zones.list, criterion)
|
||||
|
||||
cols = self.columns
|
||||
|
||||
if client.session.all_projects:
|
||||
cols.insert(1, 'project_id')
|
||||
|
||||
return cols, (utils.get_item_properties(s, cols) for s in data)
|
||||
|
||||
|
||||
class ShowZoneCommand(command.ShowOne):
|
||||
"""Show zone details"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowZoneCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Zone ID")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.zones.get(parsed_args.id)
|
||||
|
||||
_format_zone(data)
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class CreateZoneCommand(command.ShowOne):
|
||||
"""Create new zone"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateZoneCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('name', help="Zone Name")
|
||||
parser.add_argument('--email', help="Zone Email")
|
||||
parser.add_argument('--type', help="Zone Type", default='PRIMARY')
|
||||
parser.add_argument('--ttl', type=int, help="Time To Live (Seconds)")
|
||||
parser.add_argument('--description', help="Description")
|
||||
parser.add_argument('--masters', help="Zone Masters", nargs='+')
|
||||
parser.add_argument('--attributes', help="Zone Attributes", nargs='+')
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
payload = {}
|
||||
|
||||
if parsed_args.description:
|
||||
payload["description"] = parsed_args.description
|
||||
|
||||
if parsed_args.attributes:
|
||||
payload["attributes"] = {}
|
||||
for attr in parsed_args.attributes:
|
||||
try:
|
||||
k, v = attr.split(':')
|
||||
payload["attributes"][k] = v
|
||||
except ValueError:
|
||||
msg = "Attribute '%s' is in an incorrect format. "\
|
||||
"Attributes are <key>:<value> formated"
|
||||
raise osc_exc.CommandError(msg % attr)
|
||||
|
||||
if parsed_args.type == 'PRIMARY':
|
||||
# email is just for PRIMARY.
|
||||
if not parsed_args.email:
|
||||
msg = "Zone type PRIMARY requires --email."
|
||||
raise osc_exc.CommandError(msg)
|
||||
|
||||
payload["email"] = parsed_args.email
|
||||
|
||||
# TTL is just valid for PRIMARY
|
||||
if parsed_args.ttl is not None:
|
||||
payload["ttl"] = parsed_args.ttl
|
||||
elif parsed_args.type == 'SECONDARY':
|
||||
payload["masters"] = parsed_args.masters
|
||||
else:
|
||||
msg = "Type %s is not supported. Please choose between " \
|
||||
"PRIMARY or SECONDARY"
|
||||
raise osc_exc.CommandError(msg % parsed_args.type)
|
||||
|
||||
data = client.zones.create(
|
||||
parsed_args.name, parsed_args.type, **payload)
|
||||
|
||||
_format_zone(data)
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class SetZoneCommand(command.ShowOne):
|
||||
"""Set zone properties"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(SetZoneCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Zone ID")
|
||||
parser.add_argument('--email', help="Zone Email")
|
||||
parser.add_argument('--ttl', type=int, help="Time To Live (Seconds)")
|
||||
description_group = parser.add_mutually_exclusive_group()
|
||||
description_group.add_argument('--description', help="Description")
|
||||
description_group.add_argument('--no-description', action='store_true')
|
||||
|
||||
parser.add_argument('--masters', help="Zone Masters", nargs='+')
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = {}
|
||||
|
||||
# TODO(kiall): API needs updating.. this get is silly
|
||||
if parsed_args.email:
|
||||
data['email'] = parsed_args.email
|
||||
|
||||
if parsed_args.ttl:
|
||||
data['ttl'] = parsed_args.ttl
|
||||
|
||||
if parsed_args.no_description:
|
||||
data['description'] = None
|
||||
elif parsed_args.description:
|
||||
data['description'] = parsed_args.description
|
||||
|
||||
if parsed_args.masters:
|
||||
data['masters'] = parsed_args.masters
|
||||
|
||||
updated = client.zones.update(parsed_args.id, data)
|
||||
_format_zone(updated)
|
||||
return six.moves.zip(*sorted(six.iteritems(updated)))
|
||||
|
||||
|
||||
class DeleteZoneCommand(command.ShowOne):
|
||||
"""Delete zone"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteZoneCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Zone ID")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.zones.delete(parsed_args.id)
|
||||
LOG.info('Zone %s was deleted', parsed_args.id)
|
||||
|
||||
_format_zone(data)
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class AbandonZoneCommand(command.Command):
|
||||
"""Abandon a zone"""
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(AbandonZoneCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Zone ID")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
client.zones.abandon(parsed_args.id)
|
||||
|
||||
LOG.info("Z %(zone_id)s abandoned",
|
||||
{"zone_id": parsed_args.id})
|
||||
|
||||
|
||||
class AXFRZoneCommand(command.Command):
|
||||
"""AXFR a zone"""
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(AXFRZoneCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Zone ID")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
client.zones.axfr(parsed_args.id)
|
||||
|
||||
LOG.info("Scheduled AXFR for zone %(zone_id)s",
|
||||
{"zone_id": parsed_args.id})
|
||||
|
||||
|
||||
class CreateTransferRequestCommand(command.ShowOne):
|
||||
"""Create new zone transfer request"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateTransferRequestCommand, self).get_parser(
|
||||
prog_name)
|
||||
|
||||
parser.add_argument('zone_id', help="Zone ID to transfer.",)
|
||||
parser.add_argument(
|
||||
'--target-project-id',
|
||||
help="Target Project ID to transfer to.")
|
||||
parser.add_argument('--description', help="Description")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.zone_transfers.create_request(
|
||||
parsed_args.zone_id, parsed_args.target_project_id,
|
||||
parsed_args.description)
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class ListTransferRequestsCommand(command.Lister):
|
||||
"""List Zone Transfer Requests"""
|
||||
|
||||
columns = ['id', 'zone_id', 'zone_name', 'project_id',
|
||||
'target_project_id', 'status', 'key']
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListTransferRequestsCommand, self).get_parser(
|
||||
prog_name)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.zone_transfers.list_requests()
|
||||
|
||||
cols = self.columns
|
||||
return cols, (utils.get_item_properties(s, cols) for s in data)
|
||||
|
||||
|
||||
class ShowTransferRequestCommand(command.ShowOne):
|
||||
"""Show Zone Transfer Request Details"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowTransferRequestCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Zone Tranfer Request ID")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.zone_transfers.get_request(parsed_args.id)
|
||||
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class SetTransferRequestCommand(command.ShowOne):
|
||||
"""Set a Zone Transfer Request"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(SetTransferRequestCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Zone Transfer Request ID")
|
||||
description_group = parser.add_mutually_exclusive_group()
|
||||
description_group.add_argument('--description', help="Description")
|
||||
description_group.add_argument('--no-description', action='store_true')
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = {}
|
||||
|
||||
if parsed_args.no_description:
|
||||
data['description'] = None
|
||||
elif parsed_args.description:
|
||||
data['description'] = parsed_args.description
|
||||
|
||||
updated = client.zone_transfers.update_request(parsed_args.id, data)
|
||||
return six.moves.zip(*sorted(six.iteritems(updated)))
|
||||
|
||||
|
||||
class DeleteTransferRequestCommand(command.Command):
|
||||
"""Delete a Zone Transfer Request"""
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteTransferRequestCommand, self).get_parser(
|
||||
prog_name)
|
||||
|
||||
parser.add_argument('id', help="Zone Transfer Request ID")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
client.zone_transfers.delete_request(parsed_args.id)
|
||||
|
||||
LOG.info('Zone Transfer %s was deleted', parsed_args.id)
|
||||
|
||||
|
||||
class AcceptTransferRequestCommand(command.ShowOne):
|
||||
"""Accept a Zone Transfer Request"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(AcceptTransferRequestCommand, self).get_parser(
|
||||
prog_name)
|
||||
|
||||
parser.add_argument('--transfer-id', help="Transfer ID", type=str,
|
||||
required=True)
|
||||
parser.add_argument('--key', help="Transfer Key", type=str,
|
||||
required=True)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.zone_transfers.accept_request(
|
||||
parsed_args.transfer_id, parsed_args.key)
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class ListTransferAcceptsCommand(command.Lister):
|
||||
"""List Zone Transfer Accepts"""
|
||||
|
||||
columns = ['id', 'zone_id', 'project_id',
|
||||
'zone_transfer_request_id', 'status', 'key']
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListTransferAcceptsCommand, self).get_parser(
|
||||
prog_name)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.zone_transfers.list_requests()
|
||||
|
||||
cols = self.columns
|
||||
return cols, (utils.get_item_properties(s, cols) for s in data)
|
||||
|
||||
|
||||
class ShowTransferAcceptCommand(command.ShowOne):
|
||||
"""Show Zone Transfer Accept"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowTransferAcceptCommand, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument('id', help="Zone Tranfer Accept ID")
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.zone_transfers.get_accept(parsed_args.id)
|
||||
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class ExportZoneCommand(command.ShowOne):
|
||||
"""Export a Zone"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ExportZoneCommand, self).get_parser(
|
||||
prog_name)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
parser.add_argument('zone_id', help="Zone ID", type=str)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.zone_exports.create(parsed_args.zone_id)
|
||||
_format_zone_export_record(data)
|
||||
|
||||
LOG.info('Zone Export %s was created', data['id'])
|
||||
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class ListZoneExportsCommand(command.Lister):
|
||||
"""List Zone Exports"""
|
||||
|
||||
columns = [
|
||||
'id',
|
||||
'zone_id',
|
||||
'created_at',
|
||||
'status',
|
||||
]
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListZoneExportsCommand, self).get_parser(
|
||||
prog_name)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.zone_exports.list()
|
||||
|
||||
cols = self.columns
|
||||
return cols, (utils.get_item_properties(s, cols)
|
||||
for s in data['exports'])
|
||||
|
||||
|
||||
class ShowZoneExportCommand(command.ShowOne):
|
||||
"""Show a Zone Export"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowZoneExportCommand, self).get_parser(
|
||||
prog_name)
|
||||
|
||||
parser.add_argument('zone_export_id', help="Zone Export ID", type=str)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.zone_exports.get_export_record(
|
||||
parsed_args.zone_export_id)
|
||||
_format_zone_export_record(data)
|
||||
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class DeleteZoneExportCommand(command.Command):
|
||||
"""Delete a Zone Export"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteZoneExportCommand, self).get_parser(
|
||||
prog_name)
|
||||
|
||||
parser.add_argument('zone_export_id', help="Zone Export ID", type=str)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
client.zone_exports.delete(parsed_args.zone_export_id)
|
||||
|
||||
LOG.info('Zone Export %s was deleted', parsed_args.zone_export_id)
|
||||
|
||||
|
||||
class ShowZoneExportFileCommand(command.ShowOne):
|
||||
"""Show the zone file for the Zone Export"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowZoneExportFileCommand, self).get_parser(
|
||||
prog_name)
|
||||
|
||||
parser.add_argument('zone_export_id', help="Zone Export ID", type=str)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.zone_exports.get_export(parsed_args.zone_export_id)
|
||||
|
||||
return ['data'], [data]
|
||||
|
||||
|
||||
class ImportZoneCommand(command.ShowOne):
|
||||
"""Import a Zone from a file on the filesystem"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ImportZoneCommand, self).get_parser(
|
||||
prog_name)
|
||||
|
||||
parser.add_argument('zone_file_path',
|
||||
help="Path to a zone file", type=str)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
with open(parsed_args.zone_file_path, 'r') as f:
|
||||
zone_file_contents = f.read()
|
||||
|
||||
data = client.zone_imports.create(zone_file_contents)
|
||||
_format_zone_import_record(data)
|
||||
|
||||
LOG.info('Zone Import %s was created', data['id'])
|
||||
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class ListZoneImportsCommand(command.Lister):
|
||||
"""List Zone Imports"""
|
||||
|
||||
columns = [
|
||||
'id',
|
||||
'zone_id',
|
||||
'created_at',
|
||||
'status',
|
||||
'message',
|
||||
]
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListZoneImportsCommand, self).get_parser(
|
||||
prog_name)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.zone_imports.list()
|
||||
|
||||
cols = self.columns
|
||||
return cols, (utils.get_item_properties(s, cols)
|
||||
for s in data['imports'])
|
||||
|
||||
|
||||
class ShowZoneImportCommand(command.ShowOne):
|
||||
"""Show a Zone Import"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowZoneImportCommand, self).get_parser(
|
||||
prog_name)
|
||||
|
||||
parser.add_argument('zone_import_id', help="Zone Import ID", type=str)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
data = client.zone_imports.get_import_record(
|
||||
parsed_args.zone_import_id)
|
||||
_format_zone_import_record(data)
|
||||
|
||||
return six.moves.zip(*sorted(six.iteritems(data)))
|
||||
|
||||
|
||||
class DeleteZoneImportCommand(command.Command):
|
||||
"""Delete a Zone Import"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteZoneImportCommand, self).get_parser(
|
||||
prog_name)
|
||||
|
||||
parser.add_argument('zone_import_id', help="Zone Import ID", type=str)
|
||||
|
||||
common.add_all_common_options(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.dns
|
||||
common.set_all_common_headers(client, parsed_args)
|
||||
|
||||
client.zone_imports.delete(parsed_args.zone_import_id)
|
||||
|
||||
LOG.info('Zone Import %s was deleted', parsed_args.zone_import_id)
|
@@ -1,140 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 keystoneauth1 import adapter
|
||||
|
||||
from designateclient import exceptions
|
||||
from designateclient.v2.blacklists import BlacklistController
|
||||
from designateclient.v2.limits import LimitController
|
||||
from designateclient.v2.nameservers import NameServerController
|
||||
from designateclient.v2.pools import PoolController
|
||||
from designateclient.v2.quotas import QuotasController
|
||||
from designateclient.v2.recordsets import RecordSetController
|
||||
from designateclient.v2.reverse import FloatingIPController
|
||||
from designateclient.v2.service_statuses import ServiceStatusesController
|
||||
from designateclient.v2.tlds import TLDController
|
||||
from designateclient.v2.zones import ZoneController
|
||||
from designateclient.v2.zones import ZoneExportsController
|
||||
from designateclient.v2.zones import ZoneImportsController
|
||||
from designateclient.v2.zones import ZoneTransfersController
|
||||
from designateclient import version
|
||||
|
||||
|
||||
class DesignateAdapter(adapter.LegacyJsonAdapter):
|
||||
"""Adapter around LegacyJsonAdapter.
|
||||
|
||||
The user can pass a timeout keyword that will apply only to
|
||||
the Designate Client, in order:
|
||||
|
||||
- timeout keyword passed to ``request()``
|
||||
- timeout attribute on keystone session
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.timeout = kwargs.pop('timeout', None)
|
||||
self.all_projects = kwargs.pop('all_projects', False)
|
||||
self.edit_managed = kwargs.pop('edit_managed', False)
|
||||
self.sudo_project_id = kwargs.pop('sudo_project_id', None)
|
||||
super(self.__class__, self).__init__(*args, **kwargs)
|
||||
|
||||
def request(self, *args, **kwargs):
|
||||
kwargs.setdefault('raise_exc', False)
|
||||
|
||||
if self.timeout is not None:
|
||||
kwargs.setdefault('timeout', self.timeout)
|
||||
|
||||
kwargs.setdefault('headers', {})
|
||||
|
||||
if self.all_projects:
|
||||
kwargs['headers'].setdefault(
|
||||
'X-Auth-All-Projects',
|
||||
str(self.all_projects)
|
||||
)
|
||||
|
||||
if self.edit_managed:
|
||||
kwargs['headers'].setdefault(
|
||||
'X-Designate-Edit-Managed-Records',
|
||||
str(self.edit_managed)
|
||||
)
|
||||
|
||||
if self.sudo_project_id is not None:
|
||||
kwargs['headers'].setdefault(
|
||||
'X-Auth-Sudo-Project-ID',
|
||||
self.sudo_project_id
|
||||
)
|
||||
|
||||
kwargs['headers'].setdefault(
|
||||
'Content-Type', 'application/json')
|
||||
|
||||
response, body = super(self.__class__, self).request(*args, **kwargs)
|
||||
|
||||
# Decode is response, if possible
|
||||
try:
|
||||
response_payload = response.json()
|
||||
except ValueError:
|
||||
response_payload = {}
|
||||
body = response.text
|
||||
|
||||
if response.status_code == 400:
|
||||
raise exceptions.BadRequest(**response_payload)
|
||||
elif response.status_code in (401, 403):
|
||||
raise exceptions.Forbidden(**response_payload)
|
||||
elif response.status_code == 404:
|
||||
raise exceptions.NotFound(**response_payload)
|
||||
elif response.status_code == 409:
|
||||
raise exceptions.Conflict(**response_payload)
|
||||
elif response.status_code == 413:
|
||||
raise exceptions.OverQuota(**response_payload)
|
||||
elif response.status_code >= 500:
|
||||
raise exceptions.Unknown(**response_payload)
|
||||
return response, body
|
||||
|
||||
|
||||
class Client(object):
|
||||
def __init__(self, region_name=None, endpoint_type='publicURL',
|
||||
extensions=None, service_type='dns', service_name=None,
|
||||
http_log_debug=False, session=None, auth=None, timeout=None,
|
||||
endpoint_override=None, all_projects=False,
|
||||
edit_managed=False, sudo_project_id=None):
|
||||
if session is None:
|
||||
raise ValueError("A session instance is required")
|
||||
|
||||
self.session = DesignateAdapter(
|
||||
session,
|
||||
auth=auth,
|
||||
region_name=region_name,
|
||||
service_type=service_type,
|
||||
interface=endpoint_type.rstrip('URL'),
|
||||
user_agent='python-designateclient-%s' % version.version_info,
|
||||
version=('2'),
|
||||
endpoint_override=endpoint_override,
|
||||
timeout=timeout,
|
||||
all_projects=all_projects,
|
||||
edit_managed=edit_managed,
|
||||
sudo_project_id=sudo_project_id
|
||||
)
|
||||
|
||||
self.blacklists = BlacklistController(self)
|
||||
self.floatingips = FloatingIPController(self)
|
||||
self.limits = LimitController(self)
|
||||
self.nameservers = NameServerController(self)
|
||||
self.recordsets = RecordSetController(self)
|
||||
self.service_statuses = ServiceStatusesController(self)
|
||||
self.tlds = TLDController(self)
|
||||
self.zones = ZoneController(self)
|
||||
self.zone_transfers = ZoneTransfersController(self)
|
||||
self.zone_exports = ZoneExportsController(self)
|
||||
self.zone_imports = ZoneImportsController(self)
|
||||
self.pools = PoolController(self)
|
||||
self.quotas = QuotasController(self)
|
@@ -1,21 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 designateclient.v2.base import V2Controller
|
||||
|
||||
|
||||
class LimitController(V2Controller):
|
||||
def get(self):
|
||||
return self._get('/limits')
|
@@ -1,26 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 designateclient.v2.base import V2Controller
|
||||
from designateclient.v2 import utils as v2_utils
|
||||
|
||||
|
||||
class NameServerController(V2Controller):
|
||||
def list(self, zone):
|
||||
zone = v2_utils.resolve_by_name(self.client.zones.list, zone)
|
||||
|
||||
url = '/zones/%s/nameservers' % zone
|
||||
|
||||
return self._get(url, response_key='nameservers')
|
@@ -1,22 +0,0 @@
|
||||
# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
|
||||
#
|
||||
# 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 designateclient.v2.base import V2Controller
|
||||
|
||||
|
||||
class PoolController(V2Controller):
|
||||
def list(self):
|
||||
url = '/pools'
|
||||
return self._get(url, response_key='pools')
|
@@ -1,27 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 designateclient.v2.base import V2Controller
|
||||
|
||||
|
||||
class QuotasController(V2Controller):
|
||||
def list(self, project_id):
|
||||
return self._get('/quotas/%s' % project_id)
|
||||
|
||||
def update(self, project_id, values):
|
||||
return self._patch('/quotas/%s' % project_id, data=values)
|
||||
|
||||
def reset(self, project_id):
|
||||
return self._delete('/quotas/%s' % project_id)
|
@@ -1,106 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 oslo_utils import uuidutils
|
||||
import six
|
||||
|
||||
from designateclient.v2.base import V2Controller
|
||||
from designateclient.v2 import utils as v2_utils
|
||||
|
||||
|
||||
class RecordSetController(V2Controller):
|
||||
def _canonicalize_record_name(self, zone, name):
|
||||
zone_info = None
|
||||
|
||||
# If we get a zone name we'll need to get the ID of it before POST.
|
||||
if isinstance(zone, six.string_types) and not \
|
||||
uuidutils.is_uuid_like(zone):
|
||||
zone_info = self.client.zones.get(zone)
|
||||
elif isinstance(zone, dict):
|
||||
zone_info = zone
|
||||
|
||||
# We where given a name like "www" vs www.i.io., attempt to fix it on
|
||||
# the behalf of the actor.
|
||||
if not name.endswith("."):
|
||||
if not isinstance(zone_info, dict):
|
||||
zone_info = self.client.zones.get(zone)
|
||||
|
||||
name = "%s.%s" % (name, zone_info["name"])
|
||||
|
||||
return name, zone_info
|
||||
|
||||
def create(self, zone, name, type_, records, description=None,
|
||||
ttl=None):
|
||||
name, zone_info = self._canonicalize_record_name(zone, name)
|
||||
|
||||
data = {
|
||||
'name': name,
|
||||
'type': type_,
|
||||
'records': records
|
||||
}
|
||||
|
||||
if ttl is not None:
|
||||
data['ttl'] = ttl
|
||||
|
||||
if description is not None:
|
||||
data['description'] = description
|
||||
|
||||
if zone_info is not None:
|
||||
zone_id = zone_info["id"]
|
||||
else:
|
||||
zone_id = zone
|
||||
|
||||
url = '/zones/%s/recordsets' % zone_id
|
||||
return self._post(url, data=data)
|
||||
|
||||
def list(self, zone, criterion=None, marker=None, limit=None):
|
||||
zone = v2_utils.resolve_by_name(self.client.zones.list, zone)
|
||||
|
||||
url = self.build_url(
|
||||
'/zones/%s/recordsets' % zone,
|
||||
criterion, marker, limit)
|
||||
|
||||
return self._get(url, response_key='recordsets')
|
||||
|
||||
def list_all_zones(self, criterion=None, marker=None, limit=None):
|
||||
|
||||
url = self.build_url('/recordsets', criterion, marker, limit)
|
||||
|
||||
return self._get(url, response_key='recordsets')
|
||||
|
||||
def get(self, zone, recordset):
|
||||
zone = v2_utils.resolve_by_name(self.client.zones.list, zone)
|
||||
recordset = v2_utils.resolve_by_name(self.list, recordset, zone)
|
||||
|
||||
url = self.build_url('/zones/%s/recordsets/%s' % (
|
||||
zone, recordset))
|
||||
|
||||
return self._get(url)
|
||||
|
||||
def update(self, zone, recordset, values):
|
||||
zone = v2_utils.resolve_by_name(self.client.zones.list, zone)
|
||||
recordset = v2_utils.resolve_by_name(self.list, recordset, zone)
|
||||
|
||||
url = '/zones/%s/recordsets/%s' % (zone, recordset)
|
||||
|
||||
return self._put(url, data=values)
|
||||
|
||||
def delete(self, zone, recordset):
|
||||
zone = v2_utils.resolve_by_name(self.client.zones.list, zone)
|
||||
recordset = v2_utils.resolve_by_name(self.list, recordset, zone)
|
||||
|
||||
url = '/zones/%s/recordsets/%s' % (zone, recordset)
|
||||
|
||||
return self._delete(url)
|
@@ -1,49 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 designateclient.v2.base import V2Controller
|
||||
|
||||
|
||||
class FloatingIPController(V2Controller):
|
||||
def set(self, floatingip_id, ptrdname, description=None, ttl=None):
|
||||
data = {
|
||||
'ptrdname': ptrdname
|
||||
}
|
||||
|
||||
if description is not None:
|
||||
data["description"] = description
|
||||
|
||||
if ttl is not None:
|
||||
data["ttl"] = ttl
|
||||
|
||||
url = '/reverse/floatingips/%s' % floatingip_id
|
||||
return self._patch(url, data=data)
|
||||
|
||||
def list(self, criterion=None):
|
||||
url = self.build_url('/reverse/floatingips', criterion)
|
||||
|
||||
return self._get(url, response_key='floatingips')
|
||||
|
||||
def get(self, floatingip_id):
|
||||
url = '/reverse/floatingips/%s' % floatingip_id
|
||||
|
||||
return self._get(url)
|
||||
|
||||
def unset(self, floatingip_id):
|
||||
data = {"ptrdname": None}
|
||||
|
||||
url = '/reverse/floatingips/%s' % floatingip_id
|
||||
|
||||
return self._patch(url, data=data)
|
@@ -1,28 +0,0 @@
|
||||
# Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 designateclient.v2 import base
|
||||
|
||||
|
||||
class ServiceStatusesController(base.V2Controller):
|
||||
def list(self, criterion=None, marker=None, limit=None):
|
||||
url = self.build_url('/service_statuses', criterion, marker, limit)
|
||||
|
||||
return self._get(url, response_key="service_statuses")
|
||||
|
||||
def get(self, service_status_id):
|
||||
url = '/service_statuses/%s' % service_status_id
|
||||
|
||||
return self._get(url)
|
@@ -1,49 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 designateclient.v2.base import V2Controller
|
||||
from designateclient.v2 import utils as v2_utils
|
||||
|
||||
|
||||
class TLDController(V2Controller):
|
||||
def create(self, name, description=None):
|
||||
data = {
|
||||
'name': name,
|
||||
}
|
||||
|
||||
if description is not None:
|
||||
data["description"] = description
|
||||
|
||||
return self._post('/tlds', data=data)
|
||||
|
||||
def list(self, criterion=None, marker=None, limit=None):
|
||||
url = self.build_url('/tlds', criterion, marker, limit)
|
||||
|
||||
return self._get(url, response_key='tlds')
|
||||
|
||||
def get(self, tld):
|
||||
tld = v2_utils.resolve_by_name(self.list, tld)
|
||||
|
||||
return self._get('/tlds/%s' % tld)
|
||||
|
||||
def update(self, tld, values):
|
||||
tld = v2_utils.resolve_by_name(self.list, tld)
|
||||
|
||||
return self._patch('/tlds/%s' % tld, data=values)
|
||||
|
||||
def delete(self, tld):
|
||||
tld = v2_utils.resolve_by_name(self.list, tld)
|
||||
|
||||
return self._delete('/tlds/%s' % tld)
|
@@ -1,80 +0,0 @@
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Author: Endre Karlson <endre.karlson@hp.com>
|
||||
#
|
||||
# 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 oslo_utils import uuidutils
|
||||
from six import iteritems
|
||||
from six import iterkeys
|
||||
from six.moves.urllib.parse import parse_qs
|
||||
from six.moves.urllib.parse import urlparse
|
||||
|
||||
from designateclient import exceptions
|
||||
|
||||
|
||||
def resolve_by_name(func, name, *args):
|
||||
"""
|
||||
Helper to resolve a "name" a'la foo.com to it's ID by using REST api's
|
||||
query support and filtering on name.
|
||||
"""
|
||||
if uuidutils.is_uuid_like(name):
|
||||
return name
|
||||
|
||||
results = func(criterion={"name": "%s" % name}, *args)
|
||||
length = len(results)
|
||||
|
||||
if length == 1:
|
||||
return results[0]["id"]
|
||||
elif length == 0:
|
||||
raise exceptions.NotFound("Name %s didn't resolve" % name)
|
||||
else:
|
||||
msg = "Multiple matches found for %s, please use ID instead." % name
|
||||
raise exceptions.NoUniqueMatch(msg)
|
||||
|
||||
|
||||
def parse_query_from_url(url):
|
||||
"""
|
||||
Helper to get key bits of data from the "next" url returned
|
||||
from the API on collections
|
||||
:param url:
|
||||
:return: dict
|
||||
"""
|
||||
values = parse_qs(urlparse(url)[4])
|
||||
return {k: values[k][0] for k in iterkeys(values)}
|
||||
|
||||
|
||||
def get_all(function, criterion=None, args=None):
|
||||
"""
|
||||
|
||||
:param function: Function to be called to get data
|
||||
:param criterion: dict of filters to be applied
|
||||
:param args: arguments to be given to the function
|
||||
:return: DesignateList()
|
||||
"""
|
||||
|
||||
criterion = criterion or {}
|
||||
args = args or []
|
||||
|
||||
data = function(*args, criterion=criterion)
|
||||
returned_data = data
|
||||
while True:
|
||||
if data.next_page:
|
||||
for k, v in iteritems(data.next_link_criterion):
|
||||
criterion[k] = v
|
||||
data = function(*args, criterion=criterion)
|
||||
returned_data.extend(data)
|
||||
else:
|
||||
break
|
||||
|
||||
return returned_data
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user