Compare commits
59 Commits
queens-eol
...
ussuri-em
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ded5189ba | ||
|
|
1419988ace | ||
|
|
21addfcca0 | ||
|
|
56681c318e | ||
|
|
5bd1b2feeb | ||
|
|
05139e97e8 | ||
|
|
c4e27f2e6d | ||
|
|
1a98ae3101 | ||
|
|
4571dcb492 | ||
|
|
9cd38596cd | ||
|
|
17f75a9c00 | ||
|
|
6a5f46615c | ||
|
|
036ec8746a | ||
|
|
56474b54df | ||
|
|
998e72a03a | ||
|
|
7d93f625d9 | ||
|
|
3216f64d14 | ||
|
|
e5440f809d | ||
|
|
d45538cf41 | ||
|
|
ce7b872c26 | ||
|
|
a0a7b4a24b | ||
|
|
c2e7441444 | ||
|
|
5cf1f0d246 | ||
|
|
c992876f96 | ||
|
|
bc9ac570bf | ||
|
|
048b3a0bd9 | ||
|
|
58234ab51c | ||
|
|
1eb26df991 | ||
|
|
47d15a74a3 | ||
|
|
597e452dbc | ||
|
|
262799e3c0 | ||
|
|
f3c117e17c | ||
|
|
e3ed8939b8 | ||
|
|
38b2b847c8 | ||
|
|
2fe9422e04 | ||
|
|
b0011487e2 | ||
|
|
db689c650f | ||
|
|
1c2079ef71 | ||
|
|
038e2f6984 | ||
|
|
334ef1ec33 | ||
|
|
4455105df5 | ||
|
|
7aca76b32b | ||
|
|
a614c845b2 | ||
|
|
8929cad166 | ||
|
|
103d4dac05 | ||
|
|
0fe7b7c087 | ||
|
|
01d1aa0da9 | ||
|
|
71034945a3 | ||
|
|
1658f71943 | ||
|
|
e7e720ca1d | ||
|
|
c3b5d573ad | ||
|
|
2dd285549d | ||
|
|
c14a1db371 | ||
|
|
26d570239d | ||
|
|
63c9890f21 | ||
|
|
86fd679be3 | ||
|
|
84d19ef13c | ||
|
|
4c47bd020f | ||
|
|
e11f2e8006 |
@@ -2,4 +2,3 @@
|
||||
host=review.opendev.org
|
||||
port=29418
|
||||
project=openstack/python-karborclient.git
|
||||
defaultbranch=stable/queens
|
||||
|
||||
12
.zuul.yaml
12
.zuul.yaml
@@ -1,12 +1,8 @@
|
||||
- project:
|
||||
templates:
|
||||
- openstack-python-jobs
|
||||
- openstack-python35-jobs
|
||||
- check-requirements
|
||||
- publish-openstack-sphinx-docs
|
||||
- openstack-cover-jobs
|
||||
- openstack-lower-constraints-jobs
|
||||
- openstack-python3-ussuri-jobs
|
||||
- openstackclient-plugin-jobs
|
||||
check:
|
||||
jobs:
|
||||
- openstack-tox-cover:
|
||||
voting: false
|
||||
|
||||
- publish-openstack-docs-pti
|
||||
|
||||
15
README.rst
15
README.rst
@@ -2,8 +2,8 @@
|
||||
Team and repository tags
|
||||
========================
|
||||
|
||||
.. image:: https://governance.openstack.org/badges/python-karborclient.svg
|
||||
:target: https://governance.openstack.org/reference/tags/index.html
|
||||
.. image:: https://governance.openstack.org/tc/badges/python-karborclient.svg
|
||||
:target: https://governance.openstack.org/tc/reference/tags/index.html
|
||||
|
||||
.. Change things from this point on
|
||||
|
||||
@@ -12,13 +12,9 @@ Karbor
|
||||
======
|
||||
|
||||
.. image:: https://img.shields.io/pypi/v/python-karborclient.svg
|
||||
:target: https://pypi.python.org/pypi/python-karborclient/
|
||||
:target: https://pypi.org/project/python-karborclient/
|
||||
:alt: Latest Version
|
||||
|
||||
.. image:: https://img.shields.io/pypi/dm/python-karborclient.svg
|
||||
:target: https://pypi.python.org/pypi/python-karborclient/
|
||||
:alt: Downloads
|
||||
|
||||
|
||||
Karbor Mission Statement
|
||||
|
||||
@@ -35,11 +31,12 @@ Karbor Mission Statement
|
||||
* `Specs`_
|
||||
* `How to Contribute`_
|
||||
|
||||
.. _PyPi: https://pypi.python.org/pypi/python-karborclient
|
||||
.. _PyPi: https://pypi.org/project/python-karborclient
|
||||
|
||||
.. _Launchpad project: https://launchpad.net/python-karborclient
|
||||
.. _Blueprints: https://blueprints.launchpad.net/python-karborclient
|
||||
.. _Bugs: https://bugs.launchpad.net/python-karborclient
|
||||
.. _Source: https://git.openstack.org/cgit/openstack/python-karborclient
|
||||
.. _Source: https://opendev.org/openstack/python-karborclient
|
||||
.. _Specs: https://docs.openstack.org/karbor/latest/specs/index.html
|
||||
.. _How to Contribute: https://docs.openstack.org/infra/manual/developers.html
|
||||
|
||||
|
||||
5
doc/requirements.txt
Normal file
5
doc/requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
# The order of packages is significant, because pip processes them in the order
|
||||
# of appearance. Changing the order has an impact on the overall integration
|
||||
# process, which may cause wedges in the gate later.
|
||||
sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD
|
||||
openstackdocstheme>=1.18.1 # Apache-2.0
|
||||
@@ -3,12 +3,12 @@ Contributing
|
||||
============
|
||||
|
||||
General Info
|
||||
============
|
||||
------------
|
||||
|
||||
.. include:: ../../../CONTRIBUTING.rst
|
||||
|
||||
Approved Specs
|
||||
==============
|
||||
--------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
Welcome to karborclient's documentation!
|
||||
========================================================
|
||||
========================================
|
||||
|
||||
Contents:
|
||||
Contents
|
||||
--------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
@@ -12,9 +13,8 @@ Contents:
|
||||
contributor/index
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
------------------
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
############
|
||||
============
|
||||
Introduction
|
||||
############
|
||||
============
|
||||
|
||||
.. include:: ../../README.rst
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
========
|
||||
=====
|
||||
Usage
|
||||
========
|
||||
=====
|
||||
|
||||
To use karborclient in a project::
|
||||
|
||||
|
||||
@@ -25,14 +25,10 @@ OpenStack Client interface. Handles the REST calls and responses.
|
||||
# E0202: An attribute inherited from %s hide this method
|
||||
# pylint: disable=E0202
|
||||
|
||||
try:
|
||||
import simplejson as json
|
||||
except ImportError:
|
||||
import json
|
||||
|
||||
import time
|
||||
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import importutils
|
||||
import requests
|
||||
|
||||
@@ -132,7 +128,7 @@ class HTTPClient(object):
|
||||
def serialize(self, kwargs):
|
||||
if kwargs.get('json') is not None:
|
||||
kwargs['headers']['Content-Type'] = 'application/json'
|
||||
kwargs['data'] = json.dumps(kwargs['json'])
|
||||
kwargs['data'] = jsonutils.dumps(kwargs['json'])
|
||||
try:
|
||||
del kwargs['json']
|
||||
except KeyError:
|
||||
|
||||
@@ -24,7 +24,7 @@ places where actual behavior differs from the spec.
|
||||
# W0102: Dangerous default value %s as argument
|
||||
# pylint: disable=W0102
|
||||
|
||||
import json
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
import requests
|
||||
import six
|
||||
@@ -58,7 +58,7 @@ class TestResponse(requests.Response):
|
||||
# Fake the text attribute to streamline Response creation
|
||||
text = data.get('text', "")
|
||||
if isinstance(text, (dict, list)):
|
||||
self._content = json.dumps(text)
|
||||
self._content = jsonutils.dumps(text)
|
||||
default_headers = {
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
import six
|
||||
import uuid
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import encodeutils
|
||||
|
||||
import prettytable
|
||||
@@ -138,7 +138,7 @@ def dict_prettyprint(val):
|
||||
:param val: dict.
|
||||
:return: formatted json string.
|
||||
"""
|
||||
return json.dumps(val, indent=2, sort_keys=True)
|
||||
return jsonutils.dumps(val, indent=2, sort_keys=True)
|
||||
|
||||
|
||||
def json_prettyprint(val):
|
||||
@@ -147,7 +147,8 @@ def json_prettyprint(val):
|
||||
:param val: json string.
|
||||
:return: formatted json string.
|
||||
"""
|
||||
return val and json.dumps(json.loads(val), indent=2, sort_keys=True)
|
||||
return val and jsonutils.dumps(jsonutils.loads(val),
|
||||
indent=2, sort_keys=True)
|
||||
|
||||
|
||||
def find_resource(manager, name_or_id, *args, **kwargs):
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
|
||||
"""Data protection V1 checkpoint action implementations"""
|
||||
|
||||
import json
|
||||
from osc_lib.command import command
|
||||
from osc_lib import utils as osc_utils
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from karborclient.common.apiclient import exceptions
|
||||
from karborclient.i18n import _
|
||||
@@ -28,7 +28,7 @@ def format_checkpoint(checkpoint_info):
|
||||
checkpoint_info['protection_plan'] = "Name: %s\nId: %s" % (
|
||||
plan['name'], plan['id'])
|
||||
if 'resource_graph' in checkpoint_info:
|
||||
checkpoint_info['resource_graph'] = json.dumps(json.loads(
|
||||
checkpoint_info['resource_graph'] = jsonutils.dumps(jsonutils.loads(
|
||||
checkpoint_info['resource_graph']), indent=2, sort_keys=True)
|
||||
checkpoint_info.pop("links", None)
|
||||
|
||||
@@ -45,6 +45,12 @@ class ListCheckpoints(command.Lister):
|
||||
metavar='<provider_id>',
|
||||
help=_('ID of provider.'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--all-projects',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Include all projects (admin only)'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--plan_id',
|
||||
metavar='<plan_id>',
|
||||
@@ -95,12 +101,13 @@ class ListCheckpoints(command.Lister):
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)", parsed_args)
|
||||
data_protection_client = self.app.client_manager.data_protection
|
||||
|
||||
all_projects = bool(parsed_args.project_id) or parsed_args.all_projects
|
||||
search_opts = {
|
||||
'plan_id': parsed_args.plan_id,
|
||||
'start_date': parsed_args.start_date,
|
||||
'end_date': parsed_args.end_date,
|
||||
'project_id': parsed_args.project_id,
|
||||
'all_tenants': all_projects
|
||||
}
|
||||
|
||||
data = data_protection_client.checkpoints.list(
|
||||
@@ -219,3 +226,58 @@ class DeleteCheckpoint(command.Command):
|
||||
raise exceptions.CommandError(
|
||||
"Unable to find and delete any of the "
|
||||
"specified checkpoint.")
|
||||
|
||||
|
||||
class ResetCheckpointState(command.Command):
|
||||
_description = "Reset checkpoint state"
|
||||
|
||||
log = logging.getLogger(__name__ + ".ResetCheckpointState")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ResetCheckpointState, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'provider_id',
|
||||
metavar='<provider_id>',
|
||||
help=_('Id of provider.')
|
||||
)
|
||||
parser.add_argument(
|
||||
'checkpoint',
|
||||
metavar='<checkpoint>',
|
||||
nargs="+",
|
||||
help=_('Id of checkpoint.')
|
||||
)
|
||||
parser.add_argument(
|
||||
'--available',
|
||||
action='store_const', dest='state',
|
||||
default='error', const='available',
|
||||
help=_('Request the checkpoint be reset to "available" state '
|
||||
'instead of "error" state(the default).'),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.data_protection
|
||||
failure_count = 0
|
||||
for checkpoint_id in parsed_args.checkpoint:
|
||||
try:
|
||||
client.checkpoints.reset_state(
|
||||
parsed_args.provider_id, checkpoint_id, parsed_args.state)
|
||||
except exceptions.NotFound:
|
||||
failure_count += 1
|
||||
self.log.error(
|
||||
"Failed to reset state of '{0}'; checkpoint "
|
||||
"not found".format(checkpoint_id))
|
||||
except exceptions.Forbidden:
|
||||
failure_count += 1
|
||||
self.log.error(
|
||||
"Failed to reset state of '{0}'; not "
|
||||
"allowed".format(checkpoint_id))
|
||||
except exceptions.BadRequest:
|
||||
failure_count += 1
|
||||
self.log.error(
|
||||
"Failed to reset state of '{0}'; invalid input or "
|
||||
"current checkpoint state".format(checkpoint_id))
|
||||
if failure_count == len(parsed_args.checkpoint):
|
||||
raise exceptions.CommandError(
|
||||
"Unable to find or reset any of the specified "
|
||||
"checkpoint's state.")
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
"""Data protection V1 plan action implementations"""
|
||||
|
||||
import json
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from osc_lib.command import command
|
||||
@@ -28,7 +28,8 @@ def format_plan(plan_info):
|
||||
for key in ('resources', 'parameters'):
|
||||
if key not in plan_info:
|
||||
continue
|
||||
plan_info[key] = json.dumps(plan_info[key], indent=2, sort_keys=True)
|
||||
plan_info[key] = jsonutils.dumps(plan_info[key],
|
||||
indent=2, sort_keys=True)
|
||||
plan_info.pop("links", None)
|
||||
|
||||
|
||||
@@ -210,6 +211,11 @@ class UpdatePlan(command.ShowOne):
|
||||
metavar="<name>",
|
||||
help=_("A name to which the plan will be renamed.")
|
||||
)
|
||||
parser.add_argument(
|
||||
"--description",
|
||||
metavar="<description>",
|
||||
help=_("Description to which the plan will be updated.")
|
||||
)
|
||||
parser.add_argument(
|
||||
"--resources",
|
||||
metavar="<id=type=name,id=type=name>",
|
||||
@@ -227,6 +233,8 @@ class UpdatePlan(command.ShowOne):
|
||||
data = {}
|
||||
if parsed_args.name is not None:
|
||||
data['name'] = parsed_args.name
|
||||
if parsed_args.description is not None:
|
||||
data['description'] = parsed_args.description
|
||||
if parsed_args.resources is not None:
|
||||
plan_resources = utils.extract_resources(parsed_args)
|
||||
data['resources'] = plan_resources
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
"""Data protection V1 protectables action implementations"""
|
||||
|
||||
import functools
|
||||
import json
|
||||
from osc_lib.command import command
|
||||
from osc_lib import utils as osc_utils
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from karborclient.i18n import _
|
||||
from karborclient import utils
|
||||
@@ -136,7 +136,8 @@ class ListProtectableInstances(command.Lister):
|
||||
column_headers = ['Id', 'Type', 'Name', 'Dependent resources',
|
||||
'Extra info']
|
||||
|
||||
json_dumps = functools.partial(json.dumps, indent=2, sort_keys=True)
|
||||
json_dumps = functools.partial(jsonutils.dumps,
|
||||
indent=2, sort_keys=True)
|
||||
formatters = {
|
||||
"Extra info": json_dumps,
|
||||
"Dependent resources": json_dumps,
|
||||
@@ -186,7 +187,8 @@ class ShowProtectableInstance(command.ShowOne):
|
||||
parsed_args.protectable_id,
|
||||
search_opts=search_opts)
|
||||
|
||||
json_dumps = functools.partial(json.dumps, indent=2, sort_keys=True)
|
||||
json_dumps = functools.partial(jsonutils.dumps,
|
||||
indent=2, sort_keys=True)
|
||||
instance._info.pop("links", None)
|
||||
for key in ('extra_info', 'dependent_resources'):
|
||||
if key not in instance._info:
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
"""Data protection V1 provider action implementations"""
|
||||
|
||||
import functools
|
||||
import json
|
||||
from osc_lib.command import command
|
||||
from osc_lib import utils as osc_utils
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from karborclient.i18n import _
|
||||
|
||||
@@ -96,7 +96,8 @@ class ShowProvider(command.ShowOne):
|
||||
client = self.app.client_manager.data_protection
|
||||
provider = osc_utils.find_resource(client.providers,
|
||||
parsed_args.provider)
|
||||
json_dumps = functools.partial(json.dumps, indent=2, sort_keys=True)
|
||||
json_dumps = functools.partial(jsonutils.dumps,
|
||||
indent=2, sort_keys=True)
|
||||
provider._info.pop("links", None)
|
||||
if 'extended_info_schema' in provider._info:
|
||||
provider._info['extended_info_schema'] = json_dumps(
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
"""Data protection V1 restore action implementations"""
|
||||
|
||||
import functools
|
||||
import json
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from osc_lib.command import command
|
||||
@@ -31,8 +31,8 @@ def format_restore(restore_info):
|
||||
'resources_reason'):
|
||||
if key not in restore_info:
|
||||
continue
|
||||
restore_info[key] = json.dumps(restore_info[key],
|
||||
indent=2, sort_keys=True)
|
||||
restore_info[key] = jsonutils.dumps(restore_info[key],
|
||||
indent=2, sort_keys=True)
|
||||
restore_info.pop("links", None)
|
||||
|
||||
|
||||
@@ -98,7 +98,9 @@ class ListRestores(command.Lister):
|
||||
column_headers = ['Id', 'Project id', 'Provider id', 'Checkpoint id',
|
||||
'Restore target', 'Parameters', 'Status']
|
||||
|
||||
json_dumps = functools.partial(json.dumps, indent=2, sort_keys=True)
|
||||
json_dumps = functools.partial(jsonutils.dumps,
|
||||
indent=2,
|
||||
sort_keys=True)
|
||||
formatters = {
|
||||
"Parameters": json_dumps,
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
"""Data protection V1 scheduled_operations action implementations"""
|
||||
|
||||
import functools
|
||||
import json
|
||||
import six
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from osc_lib.command import command
|
||||
@@ -30,8 +30,8 @@ def format_scheduledoperation(scheduledoperation_info):
|
||||
for key in ('operation_definition', ):
|
||||
if key not in scheduledoperation_info:
|
||||
continue
|
||||
scheduledoperation_info[key] = json.dumps(scheduledoperation_info[key],
|
||||
indent=2, sort_keys=True)
|
||||
scheduledoperation_info[key] = jsonutils.dumps(
|
||||
scheduledoperation_info[key], indent=2, sort_keys=True)
|
||||
scheduledoperation_info.pop("links", None)
|
||||
|
||||
|
||||
@@ -118,7 +118,9 @@ class ListScheduledOperations(command.Lister):
|
||||
column_headers = ['Id', 'Name', 'Operation Type', 'Trigger Id',
|
||||
'Operation Definition']
|
||||
|
||||
json_dumps = functools.partial(json.dumps, indent=2, sort_keys=True)
|
||||
json_dumps = functools.partial(jsonutils.dumps,
|
||||
indent=2,
|
||||
sort_keys=True)
|
||||
formatters = {
|
||||
"Operation Definition": json_dumps,
|
||||
}
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
"""Data protection V1 verification action implementations"""
|
||||
|
||||
import functools
|
||||
import json
|
||||
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from osc_lib.command import command
|
||||
from osc_lib import utils as osc_utils
|
||||
from oslo_log import log as logging
|
||||
|
||||
from karborclient.common.apiclient import exceptions
|
||||
from karborclient.i18n import _
|
||||
@@ -31,8 +31,8 @@ def format_verification(verification_info):
|
||||
'resources_reason'):
|
||||
if key not in verification_info:
|
||||
continue
|
||||
verification_info[key] = json.dumps(verification_info[key],
|
||||
indent=2, sort_keys=True)
|
||||
verification_info[key] = jsonutils.dumps(verification_info[key],
|
||||
indent=2, sort_keys=True)
|
||||
verification_info.pop("links", None)
|
||||
|
||||
|
||||
@@ -98,7 +98,9 @@ class ListVerifications(command.Lister):
|
||||
column_headers = ['Id', 'Project id', 'Provider id', 'Checkpoint id',
|
||||
'Parameters', 'Status']
|
||||
|
||||
json_dumps = functools.partial(json.dumps, indent=2, sort_keys=True)
|
||||
json_dumps = functools.partial(jsonutils.dumps,
|
||||
indent=2,
|
||||
sort_keys=True)
|
||||
formatters = {
|
||||
"Parameters": json_dumps,
|
||||
}
|
||||
|
||||
@@ -400,9 +400,9 @@ class KarborShell(object):
|
||||
if args.api_timeout:
|
||||
kwargs['timeout'] = args.api_timeout
|
||||
|
||||
client = karbor_client.Client(api_version, endpoint, **kwargs)
|
||||
self.cs = karbor_client.Client(api_version, endpoint, **kwargs)
|
||||
|
||||
args.func(client, args)
|
||||
args.func(self.cs, args)
|
||||
|
||||
def do_bash_completion(self, args):
|
||||
"""Prints all of the commands and options to stdout."""
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
# limitations under the License.
|
||||
|
||||
import copy
|
||||
import json
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from karborclient.osc.v1 import checkpoints as osc_checkpoints
|
||||
from karborclient.tests.unit.osc.v1 import fakes
|
||||
@@ -32,7 +33,27 @@ CHECKPOINT_INFO = {
|
||||
"type": "OS::Glance::Image",
|
||||
"name": "cirros-0.3.4-x86_64-uec"}]
|
||||
},
|
||||
"resource_graph": json.dumps(
|
||||
"resource_graph": jsonutils.dumps(
|
||||
"[{'0x0': ['OS::Glance::Image', "
|
||||
"'99777fdd-8a5b-45ab-ba2c-52420008103f', "
|
||||
"'cirros-0.3.4-x86_64-uec']}, [[['0x0']]]]"
|
||||
),
|
||||
}
|
||||
|
||||
CHECKPOINT_INFO_2 = {
|
||||
"id": "a6fd95fe-0892-43b2-ad3c-e56f3a1b86b8",
|
||||
"project_id": "79b35e99a6a541b3bcede40f590d6878",
|
||||
"status": "available",
|
||||
"protection_plan": {
|
||||
"id": "3b47fd5d-21f9-4e63-8409-0acb1bffc038",
|
||||
"name": "My application",
|
||||
"provider_id": "cf56bd3e-97a7-4078-b6d5-f36246333fd9",
|
||||
"resources": [{
|
||||
"id": "99777fdd-8a5b-45ab-ba2c-52420008103f",
|
||||
"type": "OS::Glance::Image",
|
||||
"name": "cirros-0.3.4-x86_64-uec"}]
|
||||
},
|
||||
"resource_graph": jsonutils.dumps(
|
||||
"[{'0x0': ['OS::Glance::Image', "
|
||||
"'99777fdd-8a5b-45ab-ba2c-52420008103f', "
|
||||
"'cirros-0.3.4-x86_64-uec']}, [[['0x0']]]]"
|
||||
@@ -51,13 +72,13 @@ class TestCheckpoints(fakes.TestDataProtection):
|
||||
class TestListCheckpoints(TestCheckpoints):
|
||||
def setUp(self):
|
||||
super(TestListCheckpoints, self).setUp()
|
||||
self.checkpoints_mock.list.return_value = [checkpoints.Checkpoint(
|
||||
None, copy.deepcopy(CHECKPOINT_INFO))]
|
||||
|
||||
# Command to test
|
||||
self.cmd = osc_checkpoints.ListCheckpoints(self.app, None)
|
||||
|
||||
def test_checkpoints_list(self):
|
||||
self.checkpoints_mock.list.return_value = [checkpoints.Checkpoint(
|
||||
None, copy.deepcopy(CHECKPOINT_INFO))]
|
||||
arglist = ['cf56bd3e-97a7-4078-b6d5-f36246333fd9']
|
||||
verifylist = [('provider_id', 'cf56bd3e-97a7-4078-b6d5-f36246333fd9')]
|
||||
|
||||
@@ -84,6 +105,44 @@ class TestListCheckpoints(TestCheckpoints):
|
||||
'')]
|
||||
self.assertEqual(expected_data, list(data))
|
||||
|
||||
def test_checkpoints_list_with_all_projects(self):
|
||||
self.checkpoints_mock.list.return_value = [checkpoints.Checkpoint(
|
||||
None, copy.deepcopy(CHECKPOINT_INFO)), checkpoints.Checkpoint(
|
||||
None, copy.deepcopy(CHECKPOINT_INFO_2))]
|
||||
arglist = ['cf56bd3e-97a7-4078-b6d5-f36246333fd9', '--all-projects']
|
||||
verifylist = [('provider_id', 'cf56bd3e-97a7-4078-b6d5-f36246333fd9'),
|
||||
('all_projects', True)]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
|
||||
expected_columns = (
|
||||
['Id', 'Project id', 'Status', 'Protection plan', 'Metadata',
|
||||
'Created at'])
|
||||
self.assertEqual(expected_columns, columns)
|
||||
|
||||
expected_data = [(
|
||||
"dcb20606-ad71-40a3-80e4-ef0fafdad0c3",
|
||||
"e486a2f49695423ca9c47e589b948108",
|
||||
"available",
|
||||
"Name: %(name)s\nId: %(id)s" % {
|
||||
"id": "3523a271-68aa-42f5-b9ba-56e5200a2ebb",
|
||||
"name": "My application",
|
||||
},
|
||||
'',
|
||||
''), (
|
||||
"a6fd95fe-0892-43b2-ad3c-e56f3a1b86b8",
|
||||
"79b35e99a6a541b3bcede40f590d6878",
|
||||
"available",
|
||||
"Name: %(name)s\nId: %(id)s" % {
|
||||
"id": "3b47fd5d-21f9-4e63-8409-0acb1bffc038",
|
||||
"name": "My application",
|
||||
},
|
||||
'',
|
||||
'')
|
||||
]
|
||||
self.assertEqual(expected_data, list(data))
|
||||
|
||||
|
||||
class TestCreateCheckpoint(TestCheckpoints):
|
||||
def setUp(self):
|
||||
@@ -158,3 +217,38 @@ class TestDeleteCheckpoint(TestCheckpoints):
|
||||
self.checkpoints_mock.delete.assert_called_once_with(
|
||||
'cf56bd3e-97a7-4078-b6d5-f36246333fd9',
|
||||
'dcb20606-ad71-40a3-80e4-ef0fafdad0c3')
|
||||
|
||||
|
||||
class TestResetCheckpointState(TestCheckpoints):
|
||||
def setUp(self):
|
||||
super(TestResetCheckpointState, self).setUp()
|
||||
self.cmd = osc_checkpoints.ResetCheckpointState(self.app, None)
|
||||
|
||||
def test_reset_checkpoint_with_default_state(self):
|
||||
arglist = ['cf56bd3e-97a7-4078-b6d5-f36246333fd9',
|
||||
'dcb20606-ad71-40a3-80e4-ef0fafdad0c3']
|
||||
verifylist = [('provider_id', 'cf56bd3e-97a7-4078-b6d5-f36246333fd9'),
|
||||
('checkpoint',
|
||||
['dcb20606-ad71-40a3-80e4-ef0fafdad0c3']),
|
||||
('state', 'error')]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.checkpoints_mock.reset_state.assert_called_once_with(
|
||||
'cf56bd3e-97a7-4078-b6d5-f36246333fd9',
|
||||
'dcb20606-ad71-40a3-80e4-ef0fafdad0c3',
|
||||
'error')
|
||||
|
||||
def test_reset_checkpoint(self):
|
||||
arglist = ['cf56bd3e-97a7-4078-b6d5-f36246333fd9',
|
||||
'dcb20606-ad71-40a3-80e4-ef0fafdad0c3',
|
||||
'--available']
|
||||
verifylist = [('provider_id', 'cf56bd3e-97a7-4078-b6d5-f36246333fd9'),
|
||||
('checkpoint',
|
||||
['dcb20606-ad71-40a3-80e4-ef0fafdad0c3']),
|
||||
('state', 'available')]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
self.checkpoints_mock.reset_state.assert_called_once_with(
|
||||
'cf56bd3e-97a7-4078-b6d5-f36246333fd9',
|
||||
'dcb20606-ad71-40a3-80e4-ef0fafdad0c3',
|
||||
'available')
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
# limitations under the License.
|
||||
|
||||
import copy
|
||||
import json
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from karborclient.osc.v1 import restores as osc_restores
|
||||
from karborclient.tests.unit.osc.v1 import fakes
|
||||
@@ -69,7 +70,7 @@ class TestListRestores(TestRestores):
|
||||
"cf56bd3e-97a7-4078-b6d5-f36246333fd9",
|
||||
"dcb20606-ad71-40a3-80e4-ef0fafdad0c3",
|
||||
"",
|
||||
json.dumps({}),
|
||||
jsonutils.dumps({}),
|
||||
"success")]
|
||||
self.assertEqual(expected_data, list(data))
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
# limitations under the License.
|
||||
|
||||
import copy
|
||||
import json
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from karborclient.osc.v1 import verifications as osc_verifications
|
||||
from karborclient.tests.unit.osc.v1 import fakes
|
||||
@@ -67,7 +68,7 @@ class TestListVerifications(TestVerifications):
|
||||
"e486a2f49695423ca9c47e589b948108",
|
||||
"cf56bd3e-97a7-4078-b6d5-f36246333fd9",
|
||||
"dcb20606-ad71-40a3-80e4-ef0fafdad0c3",
|
||||
json.dumps({}),
|
||||
jsonutils.dumps({}),
|
||||
"success")]
|
||||
self.assertEqual(expected_data, list(data))
|
||||
|
||||
|
||||
@@ -37,12 +37,13 @@ class FakeClient(fakes.FakeClient, client.Client):
|
||||
'project_id': PROJECT_ID,
|
||||
}
|
||||
client.Client.__init__(self, 'http://endpoint', **kwargs)
|
||||
self.client = FakeHTTPClient(**kwargs)
|
||||
self.client = self.http_client
|
||||
|
||||
|
||||
class FakeHTTPClient(base_client.HTTPClient):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
def __init__(self, endpoint, **kwargs):
|
||||
super(FakeHTTPClient, self)
|
||||
self.username = 'username'
|
||||
self.password = 'password'
|
||||
self.auth_url = 'auth_url'
|
||||
@@ -50,6 +51,9 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
self.management_url = 'http://10.0.2.15:8776/v1/fake'
|
||||
self.osapi_max_limit = 1000
|
||||
self.marker = None
|
||||
self.project_id = 'project_id'
|
||||
self.auth_token = 'auth_token'
|
||||
self.region_name = 'region_name'
|
||||
|
||||
def _cs_request(self, url, method, **kwargs):
|
||||
# Check that certain things are called correctly
|
||||
@@ -92,3 +96,27 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
"headers": headers,
|
||||
})
|
||||
return r, body
|
||||
|
||||
def json_request(self, method, url, **kwargs):
|
||||
return self._cs_request(url, method, **kwargs)
|
||||
|
||||
def get_providers_1234_checkpoints(self, **kwargs):
|
||||
return 200, {}, {"checkpoints": []}
|
||||
|
||||
def get_plans(self, **kwargs):
|
||||
return 200, {}, {"plans": []}
|
||||
|
||||
def get_operation_logs(self, **kwargs):
|
||||
return 200, {}, {"operation_logs": []}
|
||||
|
||||
def get_restores(self, **kwargs):
|
||||
return 200, {}, {"restores": []}
|
||||
|
||||
def get_scheduled_operations(self, **kwargs):
|
||||
return 200, {}, {"operations": []}
|
||||
|
||||
def get_triggers(self, **kwargs):
|
||||
return 200, {}, {"triggers": []}
|
||||
|
||||
def get_verifications(self, **kwargs):
|
||||
return 200, {}, {"verifications": []}
|
||||
|
||||
@@ -20,6 +20,7 @@ mock_request_return = ({}, {'checkpoint': {}})
|
||||
|
||||
FAKE_PROVIDER_ID = "2220f8b1-975d-4621-a872-fa9afb43cb6c"
|
||||
FAKE_PLAN_ID = "3330f8b1-975d-4621-a872-fa9afb43cb6c"
|
||||
FAKE_CHECKPOINT_ID = "e4381b1a-905e-4fec-8104-b4419ccaf963"
|
||||
|
||||
|
||||
class CheckpointsTest(base.TestCaseShell):
|
||||
@@ -33,6 +34,16 @@ class CheckpointsTest(base.TestCaseShell):
|
||||
'/providers/{provider_id}/checkpoints'.format(
|
||||
provider_id=FAKE_PROVIDER_ID), headers={})
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_list_checkpoints_with_all_tenants(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
cs.checkpoints.list(provider_id=FAKE_PROVIDER_ID,
|
||||
search_opts={'all_tenants': 1})
|
||||
mock_request.assert_called_with(
|
||||
'GET',
|
||||
'/providers/{provider_id}/checkpoints?all_tenants=1'.format(
|
||||
provider_id=FAKE_PROVIDER_ID), headers={})
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_get_checkpoint(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
@@ -90,3 +101,17 @@ class CheckpointsTest(base.TestCaseShell):
|
||||
data={
|
||||
'checkpoint': {'plan_id': FAKE_PLAN_ID, 'extra-info': None}},
|
||||
headers={})
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_reset_checkpoint_state(self, mock_request):
|
||||
mock_request.return_value = ({}, {})
|
||||
cs.checkpoints.reset_state(
|
||||
FAKE_PROVIDER_ID, FAKE_CHECKPOINT_ID, 'error')
|
||||
mock_request.assert_called_with(
|
||||
'PUT',
|
||||
'/providers/{provider_id}/checkpoints/{checkpoint_id}'.format(
|
||||
provider_id=FAKE_PROVIDER_ID,
|
||||
checkpoint_id=FAKE_CHECKPOINT_ID
|
||||
),
|
||||
data={'os-resetState': {'state': 'error'}},
|
||||
headers={})
|
||||
|
||||
@@ -21,6 +21,22 @@ mock_request_return = ({}, {'operation_log': {}})
|
||||
|
||||
class OperationLogsTest(base.TestCaseShell):
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_list_operation_logs(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
cs.operation_logs.list()
|
||||
mock_request.assert_called_with(
|
||||
'GET',
|
||||
'/operation_logs', headers={})
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_list_operation_logs_with_all_tenants(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
cs.operation_logs.list(search_opts={'all_tenants': 1})
|
||||
mock_request.assert_called_with(
|
||||
'GET',
|
||||
'/operation_logs?all_tenants=1', headers={})
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_list_operation_logs_with_marker_limit(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
|
||||
@@ -30,6 +30,15 @@ class QuotaClassesTest(base.TestCaseShell):
|
||||
'/quota_classes/default',
|
||||
data={'quota_class': {'plans': 50}}, headers={})
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_quota_class_update_with_none(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
cs.quota_classes.update('default', {'plans': None})
|
||||
mock_request.assert_called_with(
|
||||
'PUT',
|
||||
'/quota_classes/default',
|
||||
data={'quota_class': {'plans': 50}}, headers={})
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_show_quota_class(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
@@ -38,3 +47,12 @@ class QuotaClassesTest(base.TestCaseShell):
|
||||
'GET',
|
||||
'/quota_classes/default',
|
||||
headers={})
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_show_quota_class_with_headers(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
cs.quota_classes.get('default', session_id='fake_session_id')
|
||||
mock_request.assert_called_with(
|
||||
'GET',
|
||||
'/quota_classes/default',
|
||||
headers={'X-Configuration-Session': 'fake_session_id'})
|
||||
|
||||
@@ -30,6 +30,15 @@ class QuotasTest(base.TestCaseShell):
|
||||
'/quotas/{project_id}'.format(project_id=fakes.PROJECT_ID),
|
||||
data={'quota': {'plans': 50}}, headers={})
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_quota_update_with_none(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
cs.quotas.update(fakes.PROJECT_ID, {'plans': None})
|
||||
mock_request.assert_called_with(
|
||||
'PUT',
|
||||
'/quotas/{project_id}'.format(project_id=fakes.PROJECT_ID),
|
||||
data={'quota': {'plans': 50}}, headers={})
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_show_quota(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
@@ -39,6 +48,15 @@ class QuotasTest(base.TestCaseShell):
|
||||
'/quotas/{project_id}'.format(project_id=fakes.PROJECT_ID),
|
||||
headers={})
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_show_quota_with_headers(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
cs.quotas.get(fakes.PROJECT_ID, False, session_id='fake_session_id')
|
||||
mock_request.assert_called_with(
|
||||
'GET',
|
||||
'/quotas/{project_id}'.format(project_id=fakes.PROJECT_ID),
|
||||
headers={'X-Configuration-Session': 'fake_session_id'})
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_show_quota_with_detail(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
@@ -58,3 +76,13 @@ class QuotasTest(base.TestCaseShell):
|
||||
'/quotas/{project_id}/defaults'.format(
|
||||
project_id=fakes.PROJECT_ID),
|
||||
headers={})
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_show_quota_default_with_headers(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
cs.quotas.defaults(fakes.PROJECT_ID, session_id='fake_session_id')
|
||||
mock_request.assert_called_with(
|
||||
'GET',
|
||||
'/quotas/{project_id}/defaults'.format(
|
||||
project_id=fakes.PROJECT_ID),
|
||||
headers={'X-Configuration-Session': 'fake_session_id'})
|
||||
|
||||
137
karborclient/tests/unit/v1/test_shell.py
Normal file
137
karborclient/tests/unit/v1/test_shell.py
Normal file
@@ -0,0 +1,137 @@
|
||||
# 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 fixtures
|
||||
import mock
|
||||
|
||||
from karborclient import shell
|
||||
from karborclient.tests.unit import base
|
||||
from karborclient.tests.unit.v1 import fakes
|
||||
|
||||
FAKE_PROVIDER_ID = '1234'
|
||||
FAKE_ENDPOINT = 'http://127.0.0.1/identity'
|
||||
|
||||
|
||||
class ShellFixture(fixtures.Fixture):
|
||||
def setUp(self):
|
||||
super(ShellFixture, self).setUp()
|
||||
self.shell = shell.KarborShell()
|
||||
|
||||
def tearDown(self):
|
||||
# For some method like test_image_meta_bad_action we are
|
||||
# testing a SystemExit to be thrown and object self.shell has
|
||||
# no time to get instantiated which is OK in this case, so
|
||||
# we make sure the method is there before launching it.
|
||||
if hasattr(self.shell, 'cs'):
|
||||
self.shell.cs.clear_callstack()
|
||||
super(ShellFixture, self).tearDown()
|
||||
|
||||
|
||||
class ShellTest(base.TestCaseShell):
|
||||
|
||||
FAKE_ENV = {
|
||||
'OS_USERNAME': 'username',
|
||||
'OS_PASSWORD': 'password',
|
||||
'OS_TENANT_NAME': 'project_id',
|
||||
'OS_AUTH_URL': 'http://no.where/v2.0',
|
||||
'OS_AUTH_TOKEN': 'fake_token'
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
"""Run before each test."""
|
||||
super(ShellTest, self).setUp()
|
||||
for var in self.FAKE_ENV:
|
||||
self.useFixture(fixtures.EnvironmentVariable(
|
||||
var, self.FAKE_ENV[var]))
|
||||
self.shell = self.useFixture(ShellFixture()).shell
|
||||
|
||||
get_endpoint = mock.MagicMock()
|
||||
get_endpoint.return_value = FAKE_ENDPOINT
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'keystoneauth1.identity.generic.token.Token.get_endpoint',
|
||||
get_endpoint))
|
||||
self.useFixture(fixtures.MonkeyPatch('karborclient.client.Client',
|
||||
fakes.FakeClient))
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'karborclient.common.http._construct_http_client',
|
||||
fakes.FakeHTTPClient))
|
||||
|
||||
def run_command(self, cmd):
|
||||
if not isinstance(cmd, list):
|
||||
cmd = cmd.split()
|
||||
self.shell.main(cmd)
|
||||
|
||||
def assert_called(self, method, url, body=None, **kwargs):
|
||||
return self.shell.cs.assert_called(method, url, body, **kwargs)
|
||||
|
||||
def test_checkpoint_list_with_all_tenants(self):
|
||||
self.run_command(
|
||||
'checkpoint-list ' + FAKE_PROVIDER_ID + ' --all-tenants 1')
|
||||
|
||||
self.assert_called('GET',
|
||||
'/providers/1234/'
|
||||
'checkpoints?all_tenants=1')
|
||||
|
||||
def test_checkpoint_list_with_all(self):
|
||||
self.run_command(
|
||||
'checkpoint-list ' + FAKE_PROVIDER_ID + ' --all')
|
||||
self.assert_called('GET',
|
||||
'/providers/1234/'
|
||||
'checkpoints?all_tenants=1')
|
||||
|
||||
def test_plan_list_with_all_tenants(self):
|
||||
self.run_command('plan-list --all-tenants 1')
|
||||
self.assert_called('GET', '/plans?all_tenants=1')
|
||||
|
||||
def test_plan_list_with_all(self):
|
||||
self.run_command('plan-list --all')
|
||||
self.assert_called('GET', '/plans?all_tenants=1')
|
||||
|
||||
def test_resotre_list_with_all_tenants(self):
|
||||
self.run_command('restore-list --all-tenants 1')
|
||||
self.assert_called('GET', '/restores?all_tenants=1')
|
||||
|
||||
def test_resotre_list_with_all(self):
|
||||
self.run_command('restore-list --all')
|
||||
self.assert_called('GET', '/restores?all_tenants=1')
|
||||
|
||||
def test_verification_list_with_all_tenants(self):
|
||||
self.run_command('verification-list --all-tenants 1')
|
||||
self.assert_called('GET', '/verifications?all_tenants=1')
|
||||
|
||||
def test_verification_list_with_all(self):
|
||||
self.run_command('verification-list --all')
|
||||
self.assert_called('GET', '/verifications?all_tenants=1')
|
||||
|
||||
def test_trigger_list_with_all_tenants(self):
|
||||
self.run_command('trigger-list --all-tenants 1')
|
||||
self.assert_called('GET', '/triggers?all_tenants=1')
|
||||
|
||||
def test_trigger_list_with_all(self):
|
||||
self.run_command('trigger-list --all')
|
||||
self.assert_called('GET', '/triggers?all_tenants=1')
|
||||
|
||||
def test_scheduledoperation_list_with_all_tenants(self):
|
||||
self.run_command('scheduledoperation-list --all-tenants 1')
|
||||
self.assert_called('GET', '/scheduled_operations?all_tenants=1')
|
||||
|
||||
def test_scheduledoperation_list_with_all(self):
|
||||
self.run_command('scheduledoperation-list --all')
|
||||
self.assert_called('GET', '/scheduled_operations?all_tenants=1')
|
||||
|
||||
def test_operationlog_list_with_all_tenants(self):
|
||||
self.run_command('operationlog-list --all-tenants 1')
|
||||
self.assert_called('GET', '/operation_logs?all_tenants=1')
|
||||
|
||||
def test_operationlog_list_with_all(self):
|
||||
self.run_command('operationlog-list --all')
|
||||
self.assert_called('GET', '/operation_logs?all_tenants=1')
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
import mock
|
||||
|
||||
from karborclient.common.apiclient import exceptions
|
||||
from karborclient.tests.unit import base
|
||||
from karborclient.tests.unit.v1 import fakes
|
||||
|
||||
@@ -21,6 +22,22 @@ mock_request_return = ({}, {'trigger_info': {'name': 'fake_name'}})
|
||||
|
||||
class TriggersTest(base.TestCaseShell):
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_list_triggers(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
cs.triggers.list()
|
||||
mock_request.assert_called_with(
|
||||
'GET',
|
||||
'/triggers', headers={})
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_list_triggers_with_all_tenants(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
cs.triggers.list(search_opts={'all_tenants': 1})
|
||||
mock_request.assert_called_with(
|
||||
'GET',
|
||||
'/triggers?all_tenants=1', headers={})
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_list_triggers_with_marker_limit(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
@@ -46,16 +63,21 @@ class TriggersTest(base.TestCaseShell):
|
||||
@mock.patch('karborclient.common.http.HTTPClient.json_request')
|
||||
def test_create_trigger(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
cs.triggers.create('name', 'time', 'properties')
|
||||
cs.triggers.create('name', 'time', {})
|
||||
mock_request.assert_called_with(
|
||||
'POST',
|
||||
'/triggers',
|
||||
data={
|
||||
'trigger_info': {'name': 'name',
|
||||
'type': 'time',
|
||||
'properties': 'properties'}},
|
||||
'properties': {}}},
|
||||
headers={})
|
||||
|
||||
def test_create_trigger_with_invalid_window(self):
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
cs.triggers.create,
|
||||
'name', 'time', {'window': 'fake'})
|
||||
|
||||
@mock.patch('karborclient.common.http.HTTPClient.raw_request')
|
||||
def test_delete_trigger(self, mock_request):
|
||||
mock_request.return_value = mock_request_return
|
||||
@@ -97,3 +119,9 @@ class TriggersTest(base.TestCaseShell):
|
||||
data=body,
|
||||
headers={}
|
||||
)
|
||||
|
||||
def test_update_trigger_with_invalid_window(self):
|
||||
trigger_id = '123'
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
cs.triggers.update,
|
||||
trigger_id, {'properties': {'window': 'fake'}})
|
||||
|
||||
@@ -43,6 +43,15 @@ class CheckpointManager(base.ManagerWithFind):
|
||||
"checkpoints" .format(provider_id=provider_id)
|
||||
return self._create(url, body, 'checkpoint')
|
||||
|
||||
def reset_state(self, provider_id, checkpoint_id, state):
|
||||
body = {'os-resetState': {'state': state}}
|
||||
return self.update(provider_id, checkpoint_id, body)
|
||||
|
||||
def update(self, provider_id, checkpoint_id, values):
|
||||
url = '/providers/{provider_id}/checkpoints/{checkpoint_id}'.format(
|
||||
provider_id=provider_id, checkpoint_id=checkpoint_id)
|
||||
return self._update(url, values)
|
||||
|
||||
def delete(self, provider_id, checkpoint_id):
|
||||
path = '/providers/{provider_id}/checkpoints/' \
|
||||
'{checkpoint_id}'.format(provider_id=provider_id,
|
||||
|
||||
@@ -26,6 +26,9 @@ class QuotaClassManager(base.ManagerWithFind):
|
||||
|
||||
def update(self, class_name, data):
|
||||
|
||||
if "plans" in data and data["plans"] is None:
|
||||
data["plans"] = 50
|
||||
|
||||
body = {"quota_class": data}
|
||||
|
||||
return self._update('/quota_classes/{class_name}'
|
||||
|
||||
@@ -26,6 +26,9 @@ class QuotaManager(base.ManagerWithFind):
|
||||
|
||||
def update(self, project_id, data):
|
||||
|
||||
if "plans" in data and data["plans"] is None:
|
||||
data["plans"] = 50
|
||||
|
||||
body = {"quota": data}
|
||||
|
||||
return self._update('/quotas/{project_id}'
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
# under the License.
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
|
||||
from datetime import datetime
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from karborclient.common.apiclient import exceptions
|
||||
@@ -31,11 +31,6 @@ from karborclient import utils as arg_utils
|
||||
const=1,
|
||||
default=0,
|
||||
help='Shows details for all tenants. Admin only.')
|
||||
@utils.arg('--all_tenants',
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg('--name',
|
||||
metavar='<name>',
|
||||
default=None,
|
||||
@@ -188,6 +183,8 @@ def do_plan_delete(cs, args):
|
||||
help="Id of plan to update.")
|
||||
@utils.arg("--name", metavar="<name>",
|
||||
help="A name to which the plan will be renamed.")
|
||||
@utils.arg("--description", metavar="<description>",
|
||||
help="Description to which the plan will be updated.")
|
||||
@utils.arg("--resources", metavar="<id=type=name,id=type=name>",
|
||||
help="Resources to which the plan will be updated.")
|
||||
@utils.arg("--status", metavar="<suspended|started>",
|
||||
@@ -197,6 +194,8 @@ def do_plan_update(cs, args):
|
||||
data = {}
|
||||
if args.name is not None:
|
||||
data['name'] = args.name
|
||||
if args.description is not None:
|
||||
data['description'] = args.description
|
||||
if args.resources is not None:
|
||||
plan_resources = arg_utils.extract_resources(args)
|
||||
data['resources'] = plan_resources
|
||||
@@ -282,11 +281,6 @@ def do_restore_create(cs, args):
|
||||
const=1,
|
||||
default=0,
|
||||
help='Shows details for all tenants. Admin only.')
|
||||
@utils.arg('--all_tenants',
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg('--status',
|
||||
metavar='<status>',
|
||||
default=None,
|
||||
@@ -349,7 +343,7 @@ def do_restore_list(cs, args):
|
||||
sortby_index = None
|
||||
else:
|
||||
sortby_index = 0
|
||||
formatters = {"Parameters": lambda obj: json.dumps(
|
||||
formatters = {"Parameters": lambda obj: jsonutils.dumps(
|
||||
obj.parameters, indent=2, sort_keys=True)}
|
||||
utils.print_list(restores, key_list, exclude_unavailable=True,
|
||||
sortby_index=sortby_index, formatters=formatters)
|
||||
@@ -412,11 +406,6 @@ def do_verification_create(cs, args):
|
||||
const=1,
|
||||
default=0,
|
||||
help='Shows details for all tenants. Admin only.')
|
||||
@utils.arg('--all_tenants',
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg('--status',
|
||||
metavar='<status>',
|
||||
default=None,
|
||||
@@ -482,7 +471,7 @@ def do_verification_list(cs, args):
|
||||
sortby_index = None
|
||||
else:
|
||||
sortby_index = 0
|
||||
formatters = {"Parameters": lambda obj: json.dumps(
|
||||
formatters = {"Parameters": lambda obj: jsonutils.dumps(
|
||||
obj.parameters, indent=2, sort_keys=True)}
|
||||
utils.print_list(verifications, key_list, exclude_unavailable=True,
|
||||
sortby_index=sortby_index, formatters=formatters)
|
||||
@@ -610,7 +599,7 @@ def do_protectable_list_instances(cs, args):
|
||||
else:
|
||||
sortby_index = 0
|
||||
|
||||
formatters = {"Dependent resources": lambda obj: json.dumps(
|
||||
formatters = {"Dependent resources": lambda obj: jsonutils.dumps(
|
||||
obj.dependent_resources, indent=2, sort_keys=True)}
|
||||
utils.print_list(instances, key_list, exclude_unavailable=True,
|
||||
sortby_index=sortby_index, formatters=formatters)
|
||||
@@ -712,6 +701,14 @@ def do_checkpoint_create(cs, args):
|
||||
json_format_list=json_format_list)
|
||||
|
||||
|
||||
@utils.arg('--all-tenants',
|
||||
dest='all_tenants',
|
||||
metavar='<0|1>',
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
default=0,
|
||||
help='Shows details for all tenants. Admin only.')
|
||||
@utils.arg('provider_id',
|
||||
metavar='<provider_id>',
|
||||
help='ID of provider.')
|
||||
@@ -785,6 +782,7 @@ def do_checkpoint_list(cs, args):
|
||||
'start_date': args.start_date,
|
||||
'end_date': args.end_date,
|
||||
'project_id': args.project_id,
|
||||
'all_tenants': args.all_tenants
|
||||
}
|
||||
|
||||
if args.sort and (args.sort_key or args.sort_dir):
|
||||
@@ -852,6 +850,45 @@ def do_checkpoint_delete(cs, args):
|
||||
"specified checkpoint.")
|
||||
|
||||
|
||||
@utils.arg('provider_id',
|
||||
metavar='<provider_id>',
|
||||
help='Id of provider.')
|
||||
@utils.arg('checkpoint',
|
||||
metavar='<checkpoint>',
|
||||
nargs="+",
|
||||
help='ID of checkpoint.')
|
||||
@utils.arg('--available',
|
||||
action='store_const',
|
||||
dest='state',
|
||||
default='error',
|
||||
const='available',
|
||||
help='Request the checkpoint be reset to "available" state instead '
|
||||
'of "error" state(the default).')
|
||||
def do_checkpoint_reset_state(cs, args):
|
||||
"""Reset state of a checkpoint."""
|
||||
failure_count = 0
|
||||
|
||||
for checkpoint_id in args.checkpoint:
|
||||
try:
|
||||
cs.checkpoints.reset_state(args.provider_id, checkpoint_id,
|
||||
args.state)
|
||||
except exceptions.NotFound:
|
||||
failure_count += 1
|
||||
print("Failed to reset state of '{0}'; checkpoint not found".
|
||||
format(checkpoint_id))
|
||||
except exceptions.Forbidden:
|
||||
failure_count += 1
|
||||
print("Failed to reset state of '{0}'; not allowed".
|
||||
format(checkpoint_id))
|
||||
except exceptions.BadRequest:
|
||||
failure_count += 1
|
||||
print("Failed to reset state of '{0}'; invalid input or "
|
||||
"current checkpoint state".format(checkpoint_id))
|
||||
if failure_count == len(args.checkpoint):
|
||||
raise exceptions.CommandError("Unable to find or reset any of the "
|
||||
"specified checkpoint's state.")
|
||||
|
||||
|
||||
@utils.arg('--all-tenants',
|
||||
dest='all_tenants',
|
||||
metavar='<0|1>',
|
||||
@@ -860,11 +897,6 @@ def do_checkpoint_delete(cs, args):
|
||||
const=1,
|
||||
default=0,
|
||||
help='Shows details for all tenants. Admin only.')
|
||||
@utils.arg('--all_tenants',
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg('--name',
|
||||
metavar='<name>',
|
||||
default=None,
|
||||
@@ -937,7 +969,7 @@ def do_trigger_list(cs, args):
|
||||
else:
|
||||
sortby_index = 0
|
||||
|
||||
formatters = {"Properties": lambda obj: json.dumps(
|
||||
formatters = {"Properties": lambda obj: jsonutils.dumps(
|
||||
obj.properties, indent=2, sort_keys=True)}
|
||||
utils.print_list(triggers, key_list, exclude_unavailable=True,
|
||||
sortby_index=sortby_index, formatters=formatters)
|
||||
@@ -970,7 +1002,8 @@ def do_trigger_update(cs, args):
|
||||
"""Update a trigger."""
|
||||
trigger_info = {}
|
||||
trigger_properties = arg_utils.extract_properties(args)
|
||||
trigger_info['name'] = args.name
|
||||
if args.name:
|
||||
trigger_info['name'] = args.name
|
||||
trigger_info['properties'] = trigger_properties
|
||||
trigger = cs.triggers.update(args.trigger_id, trigger_info)
|
||||
dict_format_list = {"properties"}
|
||||
@@ -1015,11 +1048,6 @@ def do_trigger_delete(cs, args):
|
||||
const=1,
|
||||
default=0,
|
||||
help='Shows details for all tenants. Admin only.')
|
||||
@utils.arg('--all_tenants',
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg('--name',
|
||||
metavar='<name>',
|
||||
default=None,
|
||||
@@ -1106,7 +1134,9 @@ def do_scheduledoperation_list(cs, args):
|
||||
help='Trigger name.')
|
||||
@utils.arg('operation_type',
|
||||
metavar='<operation_type>',
|
||||
help='Operation Type of scheduled operation.')
|
||||
choices=['protect', 'retention_protect'],
|
||||
help='Operation Type of scheduled operation. Valid values are '
|
||||
'"protect" or "retention_protect."')
|
||||
@utils.arg('trigger_id',
|
||||
metavar='<trigger_id>',
|
||||
help='Trigger id of scheduled operation.')
|
||||
@@ -1165,11 +1195,6 @@ def do_scheduledoperation_delete(cs, args):
|
||||
const=1,
|
||||
default=0,
|
||||
help='Shows details for all tenants. Admin only.')
|
||||
@utils.arg('--all_tenants',
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg('--status',
|
||||
metavar='<status>',
|
||||
default=None,
|
||||
@@ -1332,7 +1357,7 @@ def _quota_set_pretty_show(quotas):
|
||||
metavar='<plans>',
|
||||
type=int,
|
||||
default=None,
|
||||
help='New value for the "plans" quota.')
|
||||
help='New value for the "plans" quota. The default value is 50.')
|
||||
def do_quota_update(cs, args):
|
||||
"""Update the quotas for a project (Admin only)."""
|
||||
project_id = args.tenant
|
||||
@@ -1375,7 +1400,7 @@ def do_quota_class_show(cs, args):
|
||||
metavar='<plans>',
|
||||
type=int,
|
||||
default=None,
|
||||
help='New value for the "plans" quota.')
|
||||
help='New value for the "plans" quota. The default value is 50.')
|
||||
def do_quota_class_update(cs, args):
|
||||
"""Update the quotas for a quota class (Admin only)."""
|
||||
class_name = args.class_name
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from karborclient.common.apiclient import exceptions
|
||||
from karborclient.common import base
|
||||
|
||||
|
||||
@@ -22,6 +23,12 @@ class TriggerManager(base.ManagerWithFind):
|
||||
resource_class = Trigger
|
||||
|
||||
def create(self, name, type, properties):
|
||||
if properties.get('window', None):
|
||||
try:
|
||||
properties['window'] = int(properties['window'])
|
||||
except Exception:
|
||||
msg = 'The trigger window is not integer'
|
||||
raise exceptions.CommandError(msg)
|
||||
body = {'trigger_info': {'name': name,
|
||||
'type': type,
|
||||
'properties': properties,
|
||||
@@ -45,8 +52,14 @@ class TriggerManager(base.ManagerWithFind):
|
||||
|
||||
def update(self, trigger_id, data):
|
||||
|
||||
if data['properties'].get('window', None):
|
||||
try:
|
||||
data['properties']['window'] = int(
|
||||
data['properties']['window'])
|
||||
except Exception:
|
||||
msg = 'The trigger window is not integer'
|
||||
raise exceptions.CommandError(msg)
|
||||
body = {"trigger_info": data}
|
||||
|
||||
return self._update('/triggers/{trigger_id}'
|
||||
.format(trigger_id=trigger_id),
|
||||
body, "trigger_info")
|
||||
|
||||
88
lower-constraints.txt
Normal file
88
lower-constraints.txt
Normal file
@@ -0,0 +1,88 @@
|
||||
alabaster==0.7.10
|
||||
appdirs==1.3.0
|
||||
asn1crypto==0.23.0
|
||||
Babel==2.3.4
|
||||
cffi==1.7.0
|
||||
cliff==2.8.0
|
||||
cmd2==0.8.0
|
||||
coverage==4.0
|
||||
cryptography==2.1
|
||||
debtcollector==1.2.0
|
||||
decorator==3.4.0
|
||||
deprecation==1.0
|
||||
docutils==0.11
|
||||
dogpile.cache==0.6.2
|
||||
dulwich==0.15.0
|
||||
extras==1.0.0
|
||||
fixtures==3.0.0
|
||||
flake8==2.5.5
|
||||
hacking==0.12.0
|
||||
idna==2.6
|
||||
imagesize==0.7.1
|
||||
iso8601==0.1.11
|
||||
Jinja2==2.10
|
||||
jmespath==0.9.0
|
||||
jsonpatch==1.16
|
||||
jsonpointer==1.13
|
||||
jsonschema==2.6.0
|
||||
keystoneauth1==3.4.0
|
||||
linecache2==1.0.0
|
||||
MarkupSafe==1.0
|
||||
mccabe==0.2.1
|
||||
mock==2.0.0
|
||||
monotonic==0.6
|
||||
mox3==0.20.0
|
||||
msgpack-python==0.4.0
|
||||
munch==2.1.0
|
||||
netaddr==0.7.18
|
||||
netifaces==0.10.4
|
||||
openstackdocstheme==1.18.1
|
||||
openstacksdk==0.11.2
|
||||
os-client-config==1.28.0
|
||||
os-service-types==1.2.0
|
||||
osc-lib==1.8.0
|
||||
oslo.config==5.2.0
|
||||
oslo.context==2.19.2
|
||||
oslo.i18n==3.15.3
|
||||
oslo.log==3.36.0
|
||||
oslo.serialization==2.18.0
|
||||
oslo.utils==3.33.0
|
||||
oslotest==3.2.0
|
||||
pbr==2.0.0
|
||||
pep8==1.5.7
|
||||
positional==1.2.1
|
||||
prettytable==0.7.1
|
||||
pycparser==2.18
|
||||
pyflakes==0.8.1
|
||||
Pygments==2.2.0
|
||||
pyinotify==0.9.6
|
||||
pyOpenSSL==17.1.0
|
||||
pyparsing==2.1.0
|
||||
pyperclip==1.5.27
|
||||
python-cinderclient==3.3.0
|
||||
python-dateutil==2.5.3
|
||||
python-glanceclient==2.8.0
|
||||
python-keystoneclient==3.8.0
|
||||
python-mimeparse==1.6.0
|
||||
python-novaclient==9.1.0
|
||||
python-openstackclient==3.12.0
|
||||
python-subunit==1.0.0
|
||||
pytz==2013.6
|
||||
PyYAML==3.12
|
||||
requests-mock==1.2.0
|
||||
requests==2.14.2
|
||||
requestsexceptions==1.2.0
|
||||
rfc3986==0.3.1
|
||||
simplejson==3.5.1
|
||||
six==1.10.0
|
||||
snowballstemmer==1.2.1
|
||||
Sphinx==1.6.2
|
||||
sphinxcontrib-websupport==1.0.1
|
||||
stevedore==1.20.0
|
||||
testrepository==0.0.18
|
||||
testscenarios==0.4
|
||||
testtools==2.2.0
|
||||
traceback2==1.4.0
|
||||
unittest2==1.1.0
|
||||
warlock==1.2.0
|
||||
wrapt==1.7.0
|
||||
6
releasenotes/notes/drop-py-2-7-7a92a5906980666b.yaml
Normal file
6
releasenotes/notes/drop-py-2-7-7a92a5906980666b.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
Python 2.7 support has been dropped. Last release of python-karborclient
|
||||
to support python 2.7 is OpenStack Train. The minimum version of Python now
|
||||
supported is Python 3.6.
|
||||
@@ -3,7 +3,7 @@
|
||||
# process, which may cause wedges in the gate later.
|
||||
pbr!=2.1.0,>=2.0.0 # Apache-2.0
|
||||
PrettyTable<0.8,>=0.7.1 # BSD
|
||||
keystoneauth1>=3.3.0 # Apache-2.0
|
||||
keystoneauth1>=3.4.0 # Apache-2.0
|
||||
requests>=2.14.2 # Apache-2.0
|
||||
simplejson>=3.5.1 # MIT
|
||||
Babel!=2.4.0,>=2.3.4 # BSD
|
||||
|
||||
19
setup.cfg
19
setup.cfg
@@ -4,8 +4,8 @@ summary = Python client library for Karbor API
|
||||
description-file =
|
||||
README.rst
|
||||
author = OpenStack
|
||||
author-email = openstack-dev@lists.openstack.org
|
||||
home-page = https://docs.openstack.org/karbor/latest
|
||||
author-email = openstack-discuss@lists.openstack.org
|
||||
home-page = https://docs.openstack.org/python-karborclient/latest/
|
||||
classifier =
|
||||
Environment :: OpenStack
|
||||
Intended Audience :: Information Technology
|
||||
@@ -13,10 +13,9 @@ classifier =
|
||||
License :: OSI Approved :: Apache Software License
|
||||
Operating System :: POSIX :: Linux
|
||||
Programming Language :: Python
|
||||
Programming Language :: Python :: 2
|
||||
Programming Language :: Python :: 2.7
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3.5
|
||||
Programming Language :: Python :: 3.6
|
||||
Programming Language :: Python :: 3.7
|
||||
|
||||
[global]
|
||||
setup-hooks =
|
||||
@@ -57,6 +56,7 @@ openstack.data_protection.v1 =
|
||||
data_protection_checkpoint_show = karborclient.osc.v1.checkpoints:ShowCheckpoint
|
||||
data_protection_checkpoint_create = karborclient.osc.v1.checkpoints:CreateCheckpoint
|
||||
data_protection_checkpoint_delete = karborclient.osc.v1.checkpoints:DeleteCheckpoint
|
||||
data_protection_checkpoint_reset_state = karborclient.osc.v1.checkpoints:ResetCheckpointState
|
||||
data_protection_scheduledoperation_list = karborclient.osc.v1.scheduled_operations:ListScheduledOperations
|
||||
data_protection_scheduledoperation_show = karborclient.osc.v1.scheduled_operations:ShowScheduledOperation
|
||||
data_protection_scheduledoperation_create = karborclient.osc.v1.scheduled_operations:CreateScheduledOperation
|
||||
@@ -89,14 +89,5 @@ keywords = _ gettext ngettext l_ lazy_gettext
|
||||
mapping_file = babel.cfg
|
||||
output_file = karborclient/locale/karborclient.pot
|
||||
|
||||
[build_sphinx]
|
||||
source-dir = doc/source
|
||||
build-dir = doc/build
|
||||
all_files = 1
|
||||
warning-is-error = 1
|
||||
|
||||
[upload_sphinx]
|
||||
upload-dir = doc/build/html
|
||||
|
||||
[wheel]
|
||||
universal = 1
|
||||
|
||||
@@ -7,11 +7,9 @@ hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
|
||||
coverage!=4.4,>=4.0 # Apache-2.0
|
||||
python-subunit>=1.0.0 # Apache-2.0/BSD
|
||||
docutils>=0.11 # OSI-Approved Open Source, Public Domain
|
||||
sphinx!=1.6.6,>=1.6.2 # BSD
|
||||
openstackdocstheme>=1.18.1 # Apache-2.0
|
||||
oslotest>=3.2.0 # Apache-2.0
|
||||
python-openstackclient>=3.12.0 # Apache-2.0
|
||||
requests-mock>=1.1.0 # Apache-2.0
|
||||
requests-mock>=1.2.0 # Apache-2.0
|
||||
testrepository>=0.0.18 # Apache-2.0/BSD
|
||||
testscenarios>=0.4 # Apache-2.0/BSD
|
||||
testtools>=2.2.0 # MIT
|
||||
|
||||
31
tox.ini
31
tox.ini
@@ -1,19 +1,24 @@
|
||||
[tox]
|
||||
minversion = 2.0
|
||||
envlist = py35,py27,pypy,pep8
|
||||
minversion = 3.1.1
|
||||
envlist = py37,pypy,pep8
|
||||
skipsdist = True
|
||||
ignore_basepython_conflict = True
|
||||
|
||||
[testenv]
|
||||
basepython = python3
|
||||
usedevelop = True
|
||||
install_command = pip install {opts} {packages}
|
||||
setenv =
|
||||
VIRTUAL_ENV={envdir}
|
||||
PYTHONWARNINGS=default::DeprecationWarning
|
||||
deps =
|
||||
-c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/queens}
|
||||
-c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
|
||||
-r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
commands = python setup.py test --slowest --testr-args='{posargs}'
|
||||
whitelist_externals = rm
|
||||
commands =
|
||||
rm -f .testrepository/times.dbm
|
||||
python setup.py test --slowest --testr-args='{posargs}'
|
||||
|
||||
[testenv:pep8]
|
||||
commands = flake8
|
||||
@@ -21,18 +26,16 @@ commands = flake8
|
||||
[testenv:venv]
|
||||
commands = {posargs}
|
||||
|
||||
[testenv:functional]
|
||||
setenv =
|
||||
{[testenv]setenv}
|
||||
OS_TEST_PATH = ./karborclient/tests/functional
|
||||
passenv = OS_*
|
||||
[testenv:cover]
|
||||
commands =
|
||||
python setup.py test --coverage --testr-args='{posargs}'
|
||||
coverage report
|
||||
|
||||
[testenv:docs]
|
||||
commands = python setup.py build_sphinx
|
||||
deps =
|
||||
-c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
|
||||
-r{toxinidir}/doc/requirements.txt
|
||||
commands = sphinx-build -W -b html doc/source doc/build/html
|
||||
|
||||
[testenv:debug]
|
||||
commands = oslo_debug_helper -t karborclient/tests {posargs}
|
||||
@@ -40,6 +43,12 @@ commands = oslo_debug_helper -t karborclient/tests {posargs}
|
||||
[flake8]
|
||||
|
||||
show-source = True
|
||||
ignore =
|
||||
ignore =
|
||||
builtins = _
|
||||
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,tools
|
||||
|
||||
[testenv:lower-constraints]
|
||||
deps =
|
||||
-c{toxinidir}/lower-constraints.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
-r{toxinidir}/requirements.txt
|
||||
|
||||
Reference in New Issue
Block a user