Compare commits

..

17 Commits
0.0.1 ... 0.0.5

Author SHA1 Message Date
Jenkins
25971fd867 Merge "Return actual object, not raw, when creating" 2016-06-28 09:27:19 +00:00
Yuval Brik
0644b6e175 Return actual object, not raw, when creating
When creating objects (checkpoint, plan, restore, scheduled operation,
trigger, etc) return the actual object, and not a raw dictionary.
Because a raw dictionary was returned on create and an actual object was
returned on get, this lead to the following confusion:

  checkpoint = smaug_client.checkpoint.create(...)
  checkpoint_id = checkpoint['id']
  checkpoint = smaug_client.checkpoint.get(...)
  checkpoint_id = checkpoint.id

Change-Id: I30c8eb4468d8fba830a64f336dd6cfa7793f0b48
2016-06-22 10:49:06 +03:00
OpenStack Proposal Bot
20139d066f Updated from global requirements
Change-Id: I78e0fa4c64e4a0916f25a7016c564d2d41861483
2016-06-21 18:05:49 +00:00
Jenkins
4225036154 Merge "The parameters of plan could be an empty dict without being configured" 2016-06-20 14:22:33 +00:00
chenying
db20090283 The parameters of plan could be an empty dict without being configured
Change-Id: Ife1796048a5830df707627aa7fcceae499699bff
2016-06-20 15:41:16 +08:00
OpenStack Proposal Bot
537ce1ed60 Updated from global requirements
Change-Id: I955acc77803e5f42f7f8d4d3a9af262df3e1c493
2016-06-01 13:54:35 +00:00
chenying
18ae2eb061 Fix creating scheduled_operations error
Change-Id: I5f150a6065424adbce12e2dc08a3e1cc784ef410
Closes-Bug:#1577607
2016-05-03 14:54:07 +08:00
Jenkins
34a9e75754 Merge "Add a field parameters to resource plans" 2016-04-22 09:05:20 +00:00
Jenkins
fb37a4ad52 Merge "Remove the project_id in the url of smaugclient resource" 2016-04-22 09:02:39 +00:00
Jenkins
17342e3d01 Merge "Add show protectables instance endpoint" 2016-04-21 09:26:01 +00:00
chenying
66c6ff898c Add a field parameters to resource plans
Change-Id: I89fa8861535c32262f5c538b80000116bfab488c
Closes-Bug:#1571993
2016-04-19 19:55:45 +08:00
chenying
a1f6310356 Remove the project_id in the url of smaugclient resource
The publicURL of smaug endpoint contains the api version
and project_id. So the project_id in the url of smaugclient
resource can be removed.

Change-Id: I972e584d637781fdca4fbd03d5e3cfa81b2d76cc
Closes-Bug: #1570365
2016-04-14 23:36:22 +08:00
Jenkins
77df0bfe89 Merge "Fix missing a resource class Instances" 2016-04-10 06:45:13 +00:00
Tony Breeds
f70d2500ee Manual update from global-requirements
In Ib88adcf0a6ef09349aefd6fba981a399a73ed8dd smaug is added to
projects.txt.

This change manually runs the update code to make sure that
python-smaugclient is ready for inclusion in projects.txt

Change-Id: Id2b7eeb01dcf9a85f3c3c86b414d99b12548485d
2016-04-08 13:16:56 +10:00
Tony Breeds
923dd9b83b Switch to post-versioning
Change-Id: I90c46c1e6b89043dbccaddb493085a3de2014555
2016-04-08 13:16:56 +10:00
chenying
a54697d7bc Add show protectables instance endpoint
Change-Id: I635b1993ef40d4c29e260d28ff11714493bc37a8
Closes-Bug: #1567264
2016-04-07 17:39:45 +08:00
chenying
b8cbc418e4 Fix missing a resource class Instances
Change-Id: I9d45035c0c684bf0e645f36c3aa623b7a079fd30
Closes-Bug: #1564323
2016-03-31 17:45:11 +08:00
20 changed files with 178 additions and 166 deletions

View File

@@ -3,11 +3,11 @@
# process, which may cause wedges in the gate later.
pbr>=1.6 # Apache-2.0
PrettyTable<0.8,>=0.7 # BSD
python-keystoneclient!=1.8.0,!=2.1.0,>=1.6.0 # Apache-2.0
requests!=2.9.0,>=2.8.1 # Apache-2.0
python-keystoneclient!=1.8.0,!=2.1.0,>=1.7.0 # Apache-2.0
requests>=2.10.0 # Apache-2.0
simplejson>=2.2.0 # MIT
Babel>=1.3 # BSD
Babel>=2.3.4 # BSD
six>=1.9.0 # MIT
oslo.utils>=3.5.0 # Apache-2.0
oslo.utils>=3.11.0 # Apache-2.0
oslo.log>=1.14.0 # Apache-2.0
oslo.i18n>=2.1.0 # Apache-2.0

View File

@@ -1,6 +1,5 @@
[metadata]
name = python-smaugclient
version = 0.0.1
summary = Python client library for Smaug API
description-file =
README.rst

View File

@@ -160,10 +160,9 @@ class Manager(object):
if detailed:
detail = "/detail"
return ("/v1/%(project_id)s/%(resource_type)s%(detail)s"
return ("/%(resource_type)s%(detail)s"
"%(query_string)s" %
{"project_id": self.project_id,
"resource_type": resource_type, "detail": detail,
{"resource_type": resource_type, "detail": detail,
"query_string": query_string})
def _format_sort_param(self, sort):

View File

@@ -380,13 +380,12 @@ class SmaugShell(object):
project_domain_name=args.os_project_domain_name)
endpoint_type = args.os_endpoint_type or 'publicURL'
service_type = args.os_service_type or 'application-catalog'
service_type = args.os_service_type or 'data-protect'
if not endpoint:
endpoint = keystone_auth.get_endpoint(
keystone_session,
service_type=service_type,
region_name=args.os_region_name)
endpoint = keystone_auth.get_endpoint(
keystone_session,
service_type=service_type,
region_name=args.os_region_name)
kwargs = {
'session': keystone_session,

View File

@@ -30,8 +30,7 @@ class CheckpointsTest(base.TestCaseShell):
cs.checkpoints.list(provider_id=FAKE_PROVIDER_ID)
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/providers/{provider_id}/checkpoints'.format(
project_id=fakes.PROJECT_ID,
'/providers/{provider_id}/checkpoints'.format(
provider_id=FAKE_PROVIDER_ID), headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
@@ -40,8 +39,7 @@ class CheckpointsTest(base.TestCaseShell):
cs.checkpoints.get(FAKE_PROVIDER_ID, '1')
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/providers/{provider_id}/checkpoints/1'.format(
project_id=fakes.PROJECT_ID,
'/providers/{provider_id}/checkpoints/1'.format(
provider_id=FAKE_PROVIDER_ID), headers={})
@mock.patch('smaugclient.common.http.HTTPClient.raw_request')
@@ -50,8 +48,7 @@ class CheckpointsTest(base.TestCaseShell):
cs.checkpoints.delete(FAKE_PROVIDER_ID, '1')
mock_request.assert_called_with(
'DELETE',
'/v1/{project_id}/providers/{provider_id}/checkpoints/1'.format(
project_id=fakes.PROJECT_ID,
'/providers/{provider_id}/checkpoints/1'.format(
provider_id=FAKE_PROVIDER_ID), headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
@@ -61,10 +58,9 @@ class CheckpointsTest(base.TestCaseShell):
marker=1234, limit=2)
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/providers/{provider_id}/'
'/providers/{provider_id}/'
'checkpoints?limit=2&marker=1234'.format(
provider_id=FAKE_PROVIDER_ID,
project_id=fakes.PROJECT_ID), headers={})
provider_id=FAKE_PROVIDER_ID), headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
def test_list_checkpoints_with_sort_key_dir(self, mock_request):
@@ -73,10 +69,9 @@ class CheckpointsTest(base.TestCaseShell):
sort_key='id', sort_dir='asc')
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/providers/{provider_id}/'
'/providers/{provider_id}/'
'checkpoints?sort_dir=asc&sort_key=id'.format(
provider_id=FAKE_PROVIDER_ID,
project_id=fakes.PROJECT_ID), headers={})
provider_id=FAKE_PROVIDER_ID), headers={})
def test_list_checkpoints_with_invalid_sort_key(self):
self.assertRaises(ValueError,
@@ -89,10 +84,9 @@ class CheckpointsTest(base.TestCaseShell):
cs.checkpoints.create(FAKE_PROVIDER_ID, FAKE_PLAN_ID)
mock_request.assert_called_with(
'POST',
'/v1/{project_id}/providers/{provider_id}/'
'/providers/{provider_id}/'
'checkpoints'.format(
provider_id=FAKE_PROVIDER_ID,
project_id=fakes.PROJECT_ID),
provider_id=FAKE_PROVIDER_ID),
data={
'checkpoint': {'plan_id': FAKE_PLAN_ID}},
headers={})

View File

@@ -27,7 +27,7 @@ class PlansTest(base.TestCaseShell):
cs.plans.list(marker=1234, limit=2)
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/plans?limit=2&marker=1234'.format(
'/plans?limit=2&marker=1234'.format(
project_id=fakes.PROJECT_ID), headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
@@ -36,7 +36,7 @@ class PlansTest(base.TestCaseShell):
cs.plans.list(sort_key='id', sort_dir='asc')
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/plans?'
'/plans?'
'sort_dir=asc&sort_key=id'.format(
project_id=fakes.PROJECT_ID), headers={})
@@ -48,14 +48,15 @@ class PlansTest(base.TestCaseShell):
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
def test_create_plan(self, mock_request):
mock_request.return_value = mock_request_return
cs.plans.create('Plan name', 'provider_id', '')
cs.plans.create('Plan name', 'provider_id', '', "")
mock_request.assert_called_with(
'POST',
'/v1/efc6a88b-9096-4bb6-8634-cda182a6e12a/plans',
'/plans',
data={
'plan': {'provider_id': 'provider_id',
'name': 'Plan name',
'resources': ''}},
'resources': '',
'parameters': ''}},
headers={})
@mock.patch('smaugclient.common.http.HTTPClient.raw_request')
@@ -64,7 +65,7 @@ class PlansTest(base.TestCaseShell):
cs.plans.delete('1')
mock_request.assert_called_with(
'DELETE',
'/v1/efc6a88b-9096-4bb6-8634-cda182a6e12a/plans/1',
'/plans/1',
headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
@@ -73,7 +74,7 @@ class PlansTest(base.TestCaseShell):
cs.plans.update('1', {'name': 'Test name.'})
mock_request.assert_called_with(
'PUT',
'/v1/efc6a88b-9096-4bb6-8634-cda182a6e12a/plans/1',
'/plans/1',
data={'plan': {'name': 'Test name.'}}, headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
@@ -82,7 +83,7 @@ class PlansTest(base.TestCaseShell):
cs.plans.get('1')
mock_request.assert_called_with(
'GET',
'/v1/efc6a88b-9096-4bb6-8634-cda182a6e12a/plans/1',
'/plans/1',
headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
@@ -91,5 +92,5 @@ class PlansTest(base.TestCaseShell):
cs.plans.get('1', session_id='fake_session_id')
mock_request.assert_called_with(
'GET',
'/v1/efc6a88b-9096-4bb6-8634-cda182a6e12a/plans/1',
'/plans/1',
headers={'X-Configuration-Session': 'fake_session_id'})

View File

@@ -18,6 +18,7 @@ from smaugclient.tests.unit.v1 import fakes
cs = fakes.FakeClient()
mock_request_return = ({}, {'protectable_type': {}})
mock_instances_request_return = ({}, {'instances': {}})
mock_instance_request_return = ({}, {'instance': {}})
class ProtectablesTest(base.TestCaseShell):
@@ -28,8 +29,7 @@ class ProtectablesTest(base.TestCaseShell):
cs.protectables.list()
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/protectables'.format(
project_id=fakes.PROJECT_ID), headers={})
'/protectables', headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
def test_get_protectables(self, mock_request):
@@ -37,8 +37,16 @@ class ProtectablesTest(base.TestCaseShell):
cs.protectables.get('OS::Cinder::Volume')
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/protectables/OS::Cinder::Volume'.format(
project_id=fakes.PROJECT_ID), headers={})
'/protectables/OS::Cinder::Volume', headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
def test_get_protectables_instance(self, mock_request):
mock_request.return_value = mock_instance_request_return
cs.protectables.get_instance('OS::Cinder::Volume', '1')
mock_request.assert_called_with(
'GET',
'/protectables/OS::Cinder::Volume/'
'instances/1', headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
def test_list_protectables_instances(self, mock_request):
@@ -46,8 +54,8 @@ class ProtectablesTest(base.TestCaseShell):
cs.protectables.list_instances('OS::Cinder::Volume')
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/protectables/OS::Cinder::Volume/'
'instances'.format(project_id=fakes.PROJECT_ID), headers={})
'/protectables/OS::Cinder::Volume/'
'instances', headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
def test_list_protectables_instances_with_marker_limit(self, mock_request):
@@ -56,9 +64,8 @@ class ProtectablesTest(base.TestCaseShell):
marker=1234, limit=2)
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/protectables/OS::Cinder::Volume/'
'instances?limit=2&marker=1234'.format(
project_id=fakes.PROJECT_ID), headers={})
'/protectables/OS::Cinder::Volume/'
'instances?limit=2&marker=1234', headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
def test_list_protectables_instances_with_sort_key_dir(self, mock_request):
@@ -67,9 +74,8 @@ class ProtectablesTest(base.TestCaseShell):
sort_key='id', sort_dir='asc')
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/protectables/OS::Cinder::Volume/'
'instances?sort_dir=asc&sort_key=id'.format(
project_id=fakes.PROJECT_ID), headers={})
'/protectables/OS::Cinder::Volume/'
'instances?sort_dir=asc&sort_key=id', headers={})
def test_list_protectables_instances_with_invalid_sort_key(self):
self.assertRaises(ValueError,

View File

@@ -27,9 +27,8 @@ class ProvidersTest(base.TestCaseShell):
cs.providers.get('2220f8b1-975d-4621-a872-fa9afb43cb6c')
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/providers/'
'2220f8b1-975d-4621-a872-fa9afb43cb6c'.format(
project_id=fakes.PROJECT_ID), headers={})
'/providers/'
'2220f8b1-975d-4621-a872-fa9afb43cb6c', headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
def test_list_providers(self, mock_request):
@@ -37,8 +36,7 @@ class ProvidersTest(base.TestCaseShell):
cs.providers.list()
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/providers'.format(
project_id=fakes.PROJECT_ID), headers={})
'/providers', headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
def test_list_providers_with_marker_limit(self, mock_request):
@@ -46,8 +44,7 @@ class ProvidersTest(base.TestCaseShell):
cs.providers.list(marker=1234, limit=2)
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/providers?limit=2&marker=1234'.format(
project_id=fakes.PROJECT_ID), headers={})
'/providers?limit=2&marker=1234', headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
def test_list_providers_with_sort_key_dir(self, mock_request):
@@ -55,9 +52,8 @@ class ProvidersTest(base.TestCaseShell):
cs.providers.list(sort_key='id', sort_dir='asc')
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/providers?'
'sort_dir=asc&sort_key=id'.format(
project_id=fakes.PROJECT_ID), headers={})
'/providers?'
'sort_dir=asc&sort_key=id', headers={})
def test_list_providers_with_invalid_sort_key(self):
self.assertRaises(ValueError,

View File

@@ -27,8 +27,7 @@ class RestoresTest(base.TestCaseShell):
cs.restores.list(marker=1234, limit=2)
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/restores?limit=2&marker=1234'.format(
project_id=fakes.PROJECT_ID), headers={})
'/restores?limit=2&marker=1234', headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
def test_list_restores_with_sort_key_dir(self, mock_request):
@@ -36,9 +35,8 @@ class RestoresTest(base.TestCaseShell):
cs.restores.list(sort_key='id', sort_dir='asc')
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/restores?'
'sort_dir=asc&sort_key=id'.format(
project_id=fakes.PROJECT_ID), headers={})
'/restores?'
'sort_dir=asc&sort_key=id', headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
def test_list_plans_with_invalid_sort_key(self, mock_request):
@@ -54,7 +52,7 @@ class RestoresTest(base.TestCaseShell):
'{"username": "admin"}')
mock_request.assert_called_with(
'POST',
'/v1/efc6a88b-9096-4bb6-8634-cda182a6e12a/restores',
'/restores',
data={
'restore':
{
@@ -70,7 +68,7 @@ class RestoresTest(base.TestCaseShell):
cs.restores.get('1')
mock_request.assert_called_with(
'GET',
'/v1/efc6a88b-9096-4bb6-8634-cda182a6e12a/restores/1',
'/restores/1',
headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
@@ -79,5 +77,5 @@ class RestoresTest(base.TestCaseShell):
cs.restores.get('1', session_id='fake_session_id')
mock_request.assert_called_with(
'GET',
'/v1/efc6a88b-9096-4bb6-8634-cda182a6e12a/restores/1',
'/restores/1',
headers={'X-Configuration-Session': 'fake_session_id'})

View File

@@ -27,8 +27,7 @@ class ScheduledOperationsTest(base.TestCaseShell):
cs.scheduled_operations.list(marker=1234, limit=2)
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/scheduled_operations?limit=2&marker=1234'.format(
project_id=fakes.PROJECT_ID), headers={})
'/scheduled_operations?limit=2&marker=1234', headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
def test_list__scheduled_operations_with_sort_key_dir(self, mock_request):
@@ -36,9 +35,8 @@ class ScheduledOperationsTest(base.TestCaseShell):
cs.scheduled_operations.list(sort_key='id', sort_dir='asc')
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/scheduled_operations?'
'sort_dir=asc&sort_key=id'.format(
project_id=fakes.PROJECT_ID), headers={})
'/scheduled_operations?'
'sort_dir=asc&sort_key=id', headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
def test_list_scheduled_operations_with_invalid_sort_key(self,
@@ -56,7 +54,7 @@ class ScheduledOperationsTest(base.TestCaseShell):
'operation_definition')
mock_request.assert_called_with(
'POST',
'/v1/efc6a88b-9096-4bb6-8634-cda182a6e12a/scheduled_operations',
'/scheduled_operations',
data={
'scheduled_operation': {
'name': 'name',
@@ -71,7 +69,7 @@ class ScheduledOperationsTest(base.TestCaseShell):
cs.scheduled_operations.delete('1')
mock_request.assert_called_with(
'DELETE',
'/v1/efc6a88b-9096-4bb6-8634-cda182a6e12a/scheduled_operations/1',
'/scheduled_operations/1',
headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
@@ -80,7 +78,7 @@ class ScheduledOperationsTest(base.TestCaseShell):
cs.scheduled_operations.get('1')
mock_request.assert_called_with(
'GET',
'/v1/efc6a88b-9096-4bb6-8634-cda182a6e12a/scheduled_operations/1',
'/scheduled_operations/1',
headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
@@ -89,5 +87,5 @@ class ScheduledOperationsTest(base.TestCaseShell):
cs.scheduled_operations.get('1', session_id='fake_session_id')
mock_request.assert_called_with(
'GET',
'/v1/efc6a88b-9096-4bb6-8634-cda182a6e12a/scheduled_operations/1',
'/scheduled_operations/1',
headers={'X-Configuration-Session': 'fake_session_id'})

View File

@@ -27,8 +27,7 @@ class TriggersTest(base.TestCaseShell):
cs.triggers.list(marker=1234, limit=2)
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/triggers?limit=2&marker=1234'.format(
project_id=fakes.PROJECT_ID), headers={})
'/triggers?limit=2&marker=1234', headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
def test_list_triggers_with_sort_key_dir(self, mock_request):
@@ -36,9 +35,8 @@ class TriggersTest(base.TestCaseShell):
cs.triggers.list(sort_key='id', sort_dir='asc')
mock_request.assert_called_with(
'GET',
'/v1/{project_id}/triggers?'
'sort_dir=asc&sort_key=id'.format(
project_id=fakes.PROJECT_ID), headers={})
'/triggers?'
'sort_dir=asc&sort_key=id', headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
def test_list_triggers_with_invalid_sort_key(self, mock_request):
@@ -51,7 +49,7 @@ class TriggersTest(base.TestCaseShell):
cs.triggers.create('name', 'time', 'properties')
mock_request.assert_called_with(
'POST',
'/v1/efc6a88b-9096-4bb6-8634-cda182a6e12a/triggers',
'/triggers',
data={
'trigger_info': {'name': 'name',
'type': 'time',
@@ -64,7 +62,7 @@ class TriggersTest(base.TestCaseShell):
cs.triggers.delete('1')
mock_request.assert_called_with(
'DELETE',
'/v1/efc6a88b-9096-4bb6-8634-cda182a6e12a/triggers/1',
'/triggers/1',
headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
@@ -73,7 +71,7 @@ class TriggersTest(base.TestCaseShell):
cs.triggers.get('1')
mock_request.assert_called_with(
'GET',
'/v1/efc6a88b-9096-4bb6-8634-cda182a6e12a/triggers/1',
'/triggers/1',
headers={})
@mock.patch('smaugclient.common.http.HTTPClient.json_request')
@@ -82,5 +80,5 @@ class TriggersTest(base.TestCaseShell):
cs.triggers.get('1', session_id='fake_session_id')
mock_request.assert_called_with(
'GET',
'/v1/efc6a88b-9096-4bb6-8634-cda182a6e12a/triggers/1',
'/triggers/1',
headers={'X-Configuration-Session': 'fake_session_id'})

View File

@@ -28,15 +28,13 @@ class CheckpointManager(base.ManagerWithFind):
def create(self, provider_id, plan_id):
body = {'checkpoint': {'plan_id': plan_id}}
url = "/v1/{project_id}/providers/{provider_id}/" \
"checkpoints" .format(project_id=self.project_id,
provider_id=provider_id)
return self._create(url, body, 'checkpoint', return_raw=True)
url = "/providers/{provider_id}/" \
"checkpoints" .format(provider_id=provider_id)
return self._create(url, body, 'checkpoint')
def delete(self, provider_id, checkpoint_id):
path = '/v1/{project_id}/providers/{provider_id}/checkpoints/' \
'{checkpoint_id}'.format(project_id=self.project_id,
provider_id=provider_id,
path = '/providers/{provider_id}/checkpoints/' \
'{checkpoint_id}'.format(provider_id=provider_id,
checkpoint_id=checkpoint_id)
return self._delete(path)
@@ -45,9 +43,8 @@ class CheckpointManager(base.ManagerWithFind):
headers = {'X-Configuration-Session': session_id}
else:
headers = {}
url = '/v1/{project_id}/providers/{provider_id}/checkpoints/' \
'{checkpoint_id}'.format(project_id=self.project_id,
provider_id=provider_id,
url = '/providers/{provider_id}/checkpoints/' \
'{checkpoint_id}'.format(provider_id=provider_id,
checkpoint_id=checkpoint_id)
return self._get(url, response_key="checkpoint", headers=headers)
@@ -111,8 +108,7 @@ class CheckpointManager(base.ManagerWithFind):
params = sorted(query_params.items(), key=lambda x: x[0])
query_string = "?%s" % parse.urlencode(params)
return ("/v1/%(project_id)s/providers/%(provider_id)s"
return ("/providers/%(provider_id)s"
"/checkpoints%(query_string)s" %
{"project_id": self.project_id,
"provider_id": provider_id,
{"provider_id": provider_id,
"query_string": query_string})

View File

@@ -24,27 +24,25 @@ class Plan(base.Resource):
class PlanManager(base.ManagerWithFind):
resource_class = Plan
def create(self, name, provider_id, resources):
def create(self, name, provider_id, resources, parameters):
body = {'plan': {'name': name,
'provider_id': provider_id,
'resources': resources,
'parameters': parameters
}}
url = "/v1/{project_id}/plans" .format(
project_id=self.project_id)
return self._create(url, body, 'plan', return_raw=True)
url = "/plans"
return self._create(url, body, 'plan')
def update(self, plan_id, data):
body = {"plan": data}
return self._update('/v1/{project_id}/plans/{plan_id}'
.format(project_id=self.project_id,
plan_id=plan_id),
return self._update('/plans/{plan_id}'
.format(plan_id=plan_id),
body, "plan")
def delete(self, plan_id):
path = '/v1/{project_id}/plans/{plan_id}'.format(
project_id=self.project_id,
path = '/plans/{plan_id}'.format(
plan_id=plan_id)
return self._delete(path)
@@ -53,8 +51,7 @@ class PlanManager(base.ManagerWithFind):
headers = {'X-Configuration-Session': session_id}
else:
headers = {}
url = "/v1/{project_id}/plans/{plan_id}".format(
project_id=self.project_id,
url = "/plans/{plan_id}".format(
plan_id=plan_id)
return self._get(url, response_key="plan", headers=headers)

View File

@@ -23,6 +23,14 @@ class Protectable(base.Resource):
return self.manager.data(self, **kwargs)
class Instances(base.Resource):
def __repr__(self):
return "<Instances %s>" % self._info
def data(self, **kwargs):
return self.manager.data(self, **kwargs)
class ProtectableManager(base.ManagerWithFind):
resource_class = Protectable
@@ -31,14 +39,12 @@ class ProtectableManager(base.ManagerWithFind):
headers = {'X-Configuration-Session': session_id}
else:
headers = {}
url = "/v1/{project_id}/protectables/{protectable_type}".format(
project_id=self.project_id,
url = "/protectables/{protectable_type}".format(
protectable_type=protectable_type)
return self._get(url, response_key="protectable_type", headers=headers)
def list(self):
url = "/v1/{project_id}/protectables".format(
project_id=self.project_id)
url = "/protectables"
protectables = self._list(url, 'protectable_type', return_raw=True)
protectables_list = []
@@ -61,7 +67,7 @@ class ProtectableManager(base.ManagerWithFind):
:param sort_dir: Sort direction, should be 'desc' or 'asc'; deprecated
in kilo
:param sort: Sort information
:rtype: list of :class:`Protectable`
:rtype: list of :class:`Instances`
"""
url = self._build_instances_list_url(
@@ -69,7 +75,17 @@ class ProtectableManager(base.ManagerWithFind):
search_opts=search_opts, marker=marker,
limit=limit, sort_key=sort_key,
sort_dir=sort_dir, sort=sort)
return self._list(url, 'instances')
return self._list(url, response_key='instances', obj_class=Instances)
def get_instance(self, type, id, session_id=None):
if session_id:
headers = {'X-Configuration-Session': session_id}
else:
headers = {}
url = "/protectables/{protectable_type}/" \
"instances/{protectable_id}".format(protectable_type=type,
protectable_id=id)
return self._get(url, response_key="instance", headers=headers)
def _build_instances_list_url(self, protectable_type,
search_opts=None, marker=None, limit=None,
@@ -108,8 +124,7 @@ class ProtectableManager(base.ManagerWithFind):
params = sorted(query_params.items(), key=lambda x: x[0])
query_string = "?%s" % parse.urlencode(params)
return ("/v1/%(project_id)s/protectables/%(protectable_type)s"
return ("/protectables/%(protectable_type)s"
"/instances%(query_string)s" %
{"project_id": self.project_id,
"protectable_type": protectable_type,
{"protectable_type": protectable_type,
"query_string": query_string})

View File

@@ -29,8 +29,7 @@ class ProviderManager(base.ManagerWithFind):
headers = {'X-Configuration-Session': session_id}
else:
headers = {}
url = "/v1/{project_id}/providers/{provider_id}".format(
project_id=self.project_id,
url = "/providers/{provider_id}".format(
provider_id=provider_id)
return self._get(url, response_key="provider", headers=headers)

View File

@@ -31,13 +31,11 @@ class RestoreManager(base.ManagerWithFind):
'parameters': parameters,
}
}
url = "/v1/{project_id}/restores" .format(
project_id=self.project_id)
return self._create(url, body, 'restore', return_raw=True)
url = "/restores"
return self._create(url, body, 'restore')
def delete(self, restore_id):
path = '/v1/{project_id}/restores/{restore_id}'.format(
project_id=self.project_id,
path = '/restores/{restore_id}'.format(
restore_id=restore_id)
return self._delete(path)
@@ -46,8 +44,7 @@ class RestoreManager(base.ManagerWithFind):
headers = {'X-Configuration-Session': session_id}
else:
headers = {}
url = "/v1/{project_id}/restores/{restore_id}".format(
project_id=self.project_id,
url = "/restores/{restore_id}".format(
restore_id=restore_id)
return self._get(url, response_key="restore", headers=headers)

View File

@@ -31,14 +31,12 @@ class ScheduledOperationManager(base.ManagerWithFind):
'operation_definition':
operation_definition,
}}
url = "/v1/{project_id}/scheduled_operations" .format(
project_id=self.project_id)
return self._create(url, body, 'scheduled_operation', return_raw=True)
url = "/scheduled_operations"
return self._create(url, body, 'scheduled_operation')
def delete(self, scheduled_operation_id):
path = '/v1/{project_id}/scheduled_operations/{scheduled_operation_id}'.\
format(project_id=self.project_id,
scheduled_operation_id=scheduled_operation_id)
path = '/scheduled_operations/{scheduled_operation_id}'.\
format(scheduled_operation_id=scheduled_operation_id)
return self._delete(path)
def get(self, scheduled_operation_id, session_id=None):
@@ -46,9 +44,8 @@ class ScheduledOperationManager(base.ManagerWithFind):
headers = {'X-Configuration-Session': session_id}
else:
headers = {}
url = "/v1/{project_id}/scheduled_operations/{scheduled_operation_id}".\
format(project_id=self.project_id,
scheduled_operation_id=scheduled_operation_id)
url = "/scheduled_operations/{scheduled_operation_id}".\
format(scheduled_operation_id=scheduled_operation_id)
return self._get(url, response_key="scheduled_operation",
headers=headers)

View File

@@ -110,14 +110,25 @@ def do_plan_list(cs, args):
metavar='<provider_id>',
help='ID of provider.')
@utils.arg('resources',
metavar='<id=type,id=type>',
metavar='<id=type=name,id=type=name>',
help='Resource in list must be a dict when creating'
' a plan.The keys of resource are id and type.')
@utils.arg('--parameters',
type=str,
nargs='*',
metavar='<key=value>',
default=None,
help='The parameters of a plan.')
def do_plan_create(cs, args):
"""Create a plan."""
plan_resources = _extract_resources(args)
plan = cs.plans.create(args.name, args.provider_id, plan_resources)
utils.print_dict(plan)
if args.parameters is not None:
plan_parameters = _extract_parameters(args)
else:
plan_parameters = {}
plan = cs.plans.create(args.name, args.provider_id, plan_resources,
plan_parameters)
utils.print_dict(plan.to_dict())
@utils.arg('plan',
@@ -181,14 +192,16 @@ def _extract_resources(args):
for data in args.resources.split(','):
resource = {}
if '=' in data:
(resource_id, resource_type) = data.split('=', 1)
(resource_id, resource_type, resource_name) = data.split('=', 2)
else:
raise exceptions.CommandError(
"Unable to parse parameter resources.")
resource["id"] = resource_id
resource["type"] = resource_type
resource["name"] = resource_name
resources.append(resource)
return resources
@@ -221,10 +234,10 @@ def do_restore_create(cs, args):
restore_parameters = _extract_parameters(args)
else:
raise exceptions.CommandError(
"checkpoint_id must be provided.")
"parameters must be provided.")
restore = cs.restores.create(args.provider_id, args.checkpoint_id,
args.restore_target, restore_parameters)
utils.print_dict(restore)
utils.print_dict(restore.to_dict())
def _extract_parameters(args):
@@ -348,6 +361,19 @@ def do_protectable_show(cs, args):
utils.print_dict(protectable.to_dict())
@utils.arg('protectable_id',
metavar='<protectable_id>',
help='Protectable instance id.')
@utils.arg('protectable_type',
metavar='<protectable_type>',
help='Protectable type.')
def do_protectable_show_instance(cs, args):
"""Shows instance details."""
instance = cs.protectables.get_instance(args.protectable_type,
args.protectable_id)
utils.print_dict(instance.to_dict())
@utils.arg('protectable_type',
metavar='<protectable_type>',
help='Type of protectable.')
@@ -486,7 +512,7 @@ def do_provider_list(cs, args):
def do_checkpoint_create(cs, args):
"""Create a checkpoint."""
checkpoint = cs.checkpoints.create(args.provider_id, args.plan_id)
utils.print_dict(checkpoint)
utils.print_dict(checkpoint.to_dict())
@utils.arg('provider_id',
@@ -690,7 +716,7 @@ def do_trigger_create(cs, args):
"""Create a trigger."""
trigger_properties = _extract_properties(args)
trigger = cs.triggers.create(args.name, args.type, trigger_properties)
utils.print_dict(trigger)
utils.print_dict(trigger.to_dict())
def _extract_properties(args):
@@ -839,11 +865,11 @@ def do_scheduledoperation_list(cs, args):
def do_scheduledoperation_create(cs, args):
"""Create a scheduled operation."""
operation_definition = _extract_operation_definition(args)
scheduledoperation = cs.scheduledoperations.create(args.name,
args.operation_type,
args.trigger_id,
operation_definition)
utils.print_dict(scheduledoperation)
scheduledoperation = cs.scheduled_operations.create(args.name,
args.operation_type,
args.trigger_id,
operation_definition)
utils.print_dict(scheduledoperation.to_dict())
def _extract_operation_definition(args):

View File

@@ -29,13 +29,11 @@ class TriggerManager(base.ManagerWithFind):
'type': type,
'properties': properties,
}}
url = "/v1/{project_id}/triggers" .format(
project_id=self.project_id)
return self._create(url, body, 'trigger_info', return_raw=True)
url = "/triggers"
return self._create(url, body, 'trigger_info')
def delete(self, trigger_id):
path = '/v1/{project_id}/triggers/{trigger_id}'.format(
project_id=self.project_id,
path = '/triggers/{trigger_id}'.format(
trigger_id=trigger_id)
return self._delete(path)
@@ -44,8 +42,7 @@ class TriggerManager(base.ManagerWithFind):
headers = {'X-Configuration-Session': session_id}
else:
headers = {}
url = "/v1/{project_id}/triggers/{trigger_id}".format(
project_id=self.project_id,
url = "/triggers/{trigger_id}".format(
trigger_id=trigger_id)
return self._get(url, response_key="trigger_info", headers=headers)

View File

@@ -2,14 +2,14 @@
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
hacking>=0.10.2,<0.11 # Apache-2.0
hacking<0.11,>=0.10.2 # Apache-2.0
coverage>=3.6 # Apache-2.0
discover # BSD
python-subunit>=0.0.18 # Apache-2.0/BSD
sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3 # BSD
oslosphinx>=2.5.0,!=3.4.0 # Apache-2.0
coverage>=3.6 # Apache-2.0
discover # BSD
python-subunit>=0.0.18 # Apache-2.0/BSD
sphinx!=1.3b1,<1.3,>=1.2.1 # BSD
oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
oslotest>=1.10.0 # Apache-2.0
testrepository>=0.0.18 # Apache-2.0/BSD
testscenarios>=0.4 # Apache-2.0/BSD
testtools>=1.4.0 # MIT
testrepository>=0.0.18 # Apache-2.0/BSD
testscenarios>=0.4 # Apache-2.0/BSD
testtools>=1.4.0 # MIT