Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
@@ -1,5 +1,4 @@
|
||||
[gerrit]
|
||||
host=review.opendev.org
|
||||
host=review.openstack.org
|
||||
port=29418
|
||||
project=openstack/python-karborclient.git
|
||||
defaultbranch=stable/rocky
|
||||
|
||||
16
.zuul.yaml
16
.zuul.yaml
@@ -1,16 +1,10 @@
|
||||
- project:
|
||||
templates:
|
||||
- check-requirements
|
||||
- openstack-cover-jobs
|
||||
- openstack-lower-constraints-jobs
|
||||
- openstack-python-jobs
|
||||
- openstack-python35-jobs
|
||||
- check-requirements
|
||||
- publish-openstack-sphinx-docs
|
||||
- openstack-python36-jobs
|
||||
- openstackclient-plugin-jobs
|
||||
check:
|
||||
jobs:
|
||||
- openstack-tox-lower-constraints
|
||||
- openstack-tox-cover:
|
||||
voting: false
|
||||
|
||||
gate:
|
||||
jobs:
|
||||
- openstack-tox-lower-constraints
|
||||
- publish-openstack-docs-pti
|
||||
|
||||
@@ -15,10 +15,6 @@ Karbor
|
||||
:target: https://pypi.org/project/python-karborclient/
|
||||
:alt: Latest Version
|
||||
|
||||
.. image:: https://img.shields.io/pypi/dm/python-karborclient.svg
|
||||
:target: https://pypi.org/project/python-karborclient/
|
||||
:alt: Downloads
|
||||
|
||||
|
||||
Karbor Mission Statement
|
||||
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -210,6 +210,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 +232,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
|
||||
|
||||
@@ -39,6 +39,26 @@ CHECKPOINT_INFO = {
|
||||
),
|
||||
}
|
||||
|
||||
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": json.dumps(
|
||||
"[{'0x0': ['OS::Glance::Image', "
|
||||
"'99777fdd-8a5b-45ab-ba2c-52420008103f', "
|
||||
"'cirros-0.3.4-x86_64-uec']}, [[['0x0']]]]"
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
class TestCheckpoints(fakes.TestDataProtection):
|
||||
def setUp(self):
|
||||
@@ -51,13 +71,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 +104,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 +216,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')
|
||||
|
||||
@@ -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={})
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -46,16 +47,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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -188,6 +188,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 +199,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
|
||||
@@ -712,6 +716,19 @@ 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('--all_tenants',
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
help=argparse.SUPPRESS)
|
||||
@utils.arg('provider_id',
|
||||
metavar='<provider_id>',
|
||||
help='ID of provider.')
|
||||
@@ -785,6 +802,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 +870,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>',
|
||||
@@ -970,7 +1027,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"}
|
||||
@@ -1106,7 +1164,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.')
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -4,7 +4,7 @@ summary = Python client library for Karbor API
|
||||
description-file =
|
||||
README.rst
|
||||
author = OpenStack
|
||||
author-email = openstack-dev@lists.openstack.org
|
||||
author-email = openstack-discuss@lists.openstack.org
|
||||
home-page = https://docs.openstack.org/python-karborclient/latest/
|
||||
classifier =
|
||||
Environment :: OpenStack
|
||||
@@ -17,6 +17,7 @@ classifier =
|
||||
Programming Language :: Python :: 2.7
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3.5
|
||||
Programming Language :: Python :: 3.6
|
||||
|
||||
[global]
|
||||
setup-hooks =
|
||||
@@ -57,6 +58,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
|
||||
|
||||
2
tox.ini
2
tox.ini
@@ -10,7 +10,7 @@ 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/rocky}
|
||||
-c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
|
||||
-r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
whitelist_externals = rm
|
||||
|
||||
Reference in New Issue
Block a user