python-openstackclient 6.5.0__py3-none-any.whl → 6.6.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. openstackclient/api/api.py +3 -4
  2. openstackclient/compute/v2/server.py +12 -7
  3. openstackclient/compute/v2/server_backup.py +3 -1
  4. openstackclient/compute/v2/server_group.py +6 -2
  5. openstackclient/compute/v2/server_migration.py +3 -4
  6. openstackclient/image/v1/image.py +32 -5
  7. openstackclient/image/v2/image.py +81 -100
  8. openstackclient/image/v2/metadef_objects.py +36 -0
  9. openstackclient/network/v2/network_flavor.py +1 -1
  10. openstackclient/tests/unit/compute/v2/test_server.py +4 -2
  11. openstackclient/tests/unit/compute/v2/test_server_group.py +5 -5
  12. openstackclient/tests/unit/compute/v2/test_server_migration.py +3 -1
  13. openstackclient/tests/unit/image/v1/test_image.py +2 -2
  14. openstackclient/tests/unit/image/v2/test_metadef_objects.py +38 -0
  15. openstackclient/volume/v2/volume_backup.py +3 -3
  16. {python_openstackclient-6.5.0.dist-info → python_openstackclient-6.6.1.dist-info}/AUTHORS +1 -0
  17. {python_openstackclient-6.5.0.dist-info → python_openstackclient-6.6.1.dist-info}/METADATA +2 -1
  18. {python_openstackclient-6.5.0.dist-info → python_openstackclient-6.6.1.dist-info}/RECORD +23 -23
  19. {python_openstackclient-6.5.0.dist-info → python_openstackclient-6.6.1.dist-info}/entry_points.txt +1 -0
  20. python_openstackclient-6.6.1.dist-info/pbr.json +1 -0
  21. python_openstackclient-6.5.0.dist-info/pbr.json +0 -1
  22. {python_openstackclient-6.5.0.dist-info → python_openstackclient-6.6.1.dist-info}/LICENSE +0 -0
  23. {python_openstackclient-6.5.0.dist-info → python_openstackclient-6.6.1.dist-info}/WHEEL +0 -0
  24. {python_openstackclient-6.5.0.dist-info → python_openstackclient-6.6.1.dist-info}/top_level.txt +0 -0
@@ -12,11 +12,10 @@
12
12
  #
13
13
 
14
14
  """Base API Library"""
15
-
16
15
  from keystoneauth1 import exceptions as ks_exceptions
17
16
  from keystoneauth1 import session as ks_session
18
17
  from osc_lib import exceptions
19
- import simplejson as json
18
+ import requests
20
19
 
21
20
  from openstackclient.i18n import _
22
21
 
@@ -118,7 +117,7 @@ class BaseAPI(KeystoneSession):
118
117
  # Should this move into _requests()?
119
118
  try:
120
119
  return ret.json()
121
- except json.JSONDecodeError:
120
+ except requests.JSONDecodeError:
122
121
  return ret
123
122
 
124
123
  def delete(self, url, session=None, **params):
@@ -169,7 +168,7 @@ class BaseAPI(KeystoneSession):
169
168
  )
170
169
  try:
171
170
  return ret.json()
172
- except json.JSONDecodeError:
171
+ except requests.JSONDecodeError:
173
172
  return ret
174
173
 
175
174
  # Layered actions built on top of the basic action methods do not
@@ -2555,10 +2555,9 @@ class ListServer(command.Lister):
2555
2555
  # flavor name is given, map it to ID.
2556
2556
  flavor_id = None
2557
2557
  if parsed_args.flavor:
2558
- flavor = compute_client.find_flavor(parsed_args.flavor)
2559
- if flavor is None:
2560
- msg = _('Unable to find flavor: %s') % parsed_args.flavor
2561
- raise exceptions.CommandError(msg)
2558
+ flavor = compute_client.find_flavor(
2559
+ parsed_args.flavor, ignore_missing=False
2560
+ )
2562
2561
  flavor_id = flavor.id
2563
2562
 
2564
2563
  # Nova only supports list servers searching by image ID. So if a
@@ -2811,7 +2810,9 @@ class ListServer(command.Lister):
2811
2810
  if parsed_args.deleted:
2812
2811
  marker_id = parsed_args.marker
2813
2812
  else:
2814
- marker_id = compute_client.find_server(parsed_args.marker).id
2813
+ marker_id = compute_client.find_server(
2814
+ parsed_args.marker, ignore_missing=False
2815
+ ).id
2815
2816
  search_opts['marker'] = marker_id
2816
2817
 
2817
2818
  data = list(compute_client.servers(**search_opts))
@@ -2871,7 +2872,9 @@ class ListServer(command.Lister):
2871
2872
  # "Flavor Name" is not crucial, so we swallow any
2872
2873
  # exceptions
2873
2874
  try:
2874
- flavors[f_id] = compute_client.find_flavor(f_id)
2875
+ flavors[f_id] = compute_client.find_flavor(
2876
+ f_id, ignore_missing=False
2877
+ )
2875
2878
  except Exception:
2876
2879
  pass
2877
2880
  else:
@@ -4039,7 +4042,9 @@ server booted from a volume."""
4039
4042
 
4040
4043
  image = None
4041
4044
  if parsed_args.image:
4042
- image = image_client.find_image(parsed_args.image)
4045
+ image = image_client.find_image(
4046
+ parsed_args.image, ignore_missing=False
4047
+ )
4043
4048
 
4044
4049
  utils.find_resource(
4045
4050
  compute_client.servers,
@@ -73,7 +73,9 @@ class CreateServerBackup(command.ShowOne):
73
73
 
74
74
  compute_client = self.app.client_manager.sdk_connection.compute
75
75
 
76
- server = compute_client.find_server(parsed_args.server)
76
+ server = compute_client.find_server(
77
+ parsed_args.server, ignore_missing=False
78
+ )
77
79
 
78
80
  # Set sane defaults as this API wants all mouths to be fed
79
81
  if parsed_args.name is None:
@@ -157,7 +157,9 @@ class DeleteServerGroup(command.Command):
157
157
  result = 0
158
158
  for group in parsed_args.server_group:
159
159
  try:
160
- group_obj = compute_client.find_server_group(group)
160
+ group_obj = compute_client.find_server_group(
161
+ group, ignore_missing=False
162
+ )
161
163
  compute_client.delete_server_group(group_obj.id)
162
164
  # Catch all exceptions in order to avoid to block the next deleting
163
165
  except Exception as e:
@@ -263,7 +265,9 @@ class ShowServerGroup(command.ShowOne):
263
265
 
264
266
  def take_action(self, parsed_args):
265
267
  compute_client = self.app.client_manager.sdk_connection.compute
266
- group = compute_client.find_server_group(parsed_args.server_group)
268
+ group = compute_client.find_server_group(
269
+ parsed_args.server_group, ignore_missing=False
270
+ )
267
271
  display_columns, columns = _get_server_group_columns(
268
272
  group,
269
273
  compute_client,
@@ -166,10 +166,9 @@ class ListMigration(command.Lister):
166
166
  search_opts['status'] = parsed_args.status
167
167
 
168
168
  if parsed_args.server:
169
- server = compute_client.find_server(parsed_args.server)
170
- if server is None:
171
- msg = _('Unable to find server: %s') % parsed_args.server
172
- raise exceptions.CommandError(msg)
169
+ server = compute_client.find_server(
170
+ parsed_args.server, ignore_missing=False
171
+ )
173
172
  search_opts['instance_uuid'] = server.id
174
173
 
175
174
  if parsed_args.type:
@@ -26,6 +26,7 @@ from osc_lib.api import utils as api_utils
26
26
  from osc_lib.cli import format_columns
27
27
  from osc_lib.cli import parseractions
28
28
  from osc_lib.command import command
29
+ from osc_lib import exceptions
29
30
  from osc_lib import utils
30
31
 
31
32
  from openstackclient.i18n import _
@@ -372,10 +373,30 @@ class DeleteImage(command.Command):
372
373
  return parser
373
374
 
374
375
  def take_action(self, parsed_args):
376
+ result = 0
375
377
  image_client = self.app.client_manager.image
376
378
  for image in parsed_args.images:
377
- image_obj = image_client.find_image(image)
378
- image_client.delete_image(image_obj.id)
379
+ try:
380
+ image_obj = image_client.find_image(
381
+ image,
382
+ ignore_missing=False,
383
+ )
384
+ image_client.delete_image(image_obj.id)
385
+ except Exception as e:
386
+ result += 1
387
+ msg = _(
388
+ "Failed to delete image with name or "
389
+ "ID '%(image)s': %(e)s"
390
+ )
391
+ LOG.error(msg, {'image': image, 'e': e})
392
+
393
+ total = len(parsed_args.images)
394
+ if result > 0:
395
+ msg = _("Failed to delete %(result)s of %(total)s images.") % {
396
+ 'result': result,
397
+ 'total': total,
398
+ }
399
+ raise exceptions.CommandError(msg)
379
400
 
380
401
 
381
402
  class ListImage(command.Lister):
@@ -528,7 +549,9 @@ class SaveImage(command.Command):
528
549
 
529
550
  def take_action(self, parsed_args):
530
551
  image_client = self.app.client_manager.image
531
- image = image_client.find_image(parsed_args.image)
552
+ image = image_client.find_image(
553
+ parsed_args.image, ignore_missing=False
554
+ )
532
555
 
533
556
  output_file = parsed_args.file
534
557
  if output_file is None:
@@ -719,7 +742,9 @@ class SetImage(command.Command):
719
742
 
720
743
  # Wrap the call to catch exceptions in order to close files
721
744
  try:
722
- image = image_client.find_image(parsed_args.image)
745
+ image = image_client.find_image(
746
+ parsed_args.image, ignore_missing=False
747
+ )
723
748
 
724
749
  if not parsed_args.location and not parsed_args.copy_from:
725
750
  if parsed_args.volume:
@@ -800,7 +825,9 @@ class ShowImage(command.ShowOne):
800
825
 
801
826
  def take_action(self, parsed_args):
802
827
  image_client = self.app.client_manager.image
803
- image = image_client.find_image(parsed_args.image)
828
+ image = image_client.find_image(
829
+ parsed_args.image, ignore_missing=False
830
+ )
804
831
 
805
832
  if parsed_args.human_readable:
806
833
  _formatters['size'] = HumanReadableSizeColumn
@@ -163,6 +163,67 @@ def get_data_from_stdin():
163
163
  return None
164
164
 
165
165
 
166
+ def _add_is_protected_args(parser):
167
+ protected_group = parser.add_mutually_exclusive_group()
168
+ protected_group.add_argument(
169
+ "--protected",
170
+ action="store_true",
171
+ dest="is_protected",
172
+ default=None,
173
+ help=_("Prevent image from being deleted"),
174
+ )
175
+ protected_group.add_argument(
176
+ "--unprotected",
177
+ action="store_false",
178
+ dest="is_protected",
179
+ default=None,
180
+ help=_("Allow image to be deleted (default)"),
181
+ )
182
+
183
+
184
+ def _add_visibility_args(parser):
185
+ public_group = parser.add_mutually_exclusive_group()
186
+ public_group.add_argument(
187
+ "--public",
188
+ action="store_const",
189
+ const="public",
190
+ dest="visibility",
191
+ help=_("Image is accessible and visible to all users"),
192
+ )
193
+ public_group.add_argument(
194
+ "--private",
195
+ action="store_const",
196
+ const="private",
197
+ dest="visibility",
198
+ help=_(
199
+ "Image is only accessible by the owner "
200
+ "(default until --os-image-api-version 2.5)"
201
+ ),
202
+ )
203
+ public_group.add_argument(
204
+ "--community",
205
+ action="store_const",
206
+ const="community",
207
+ dest="visibility",
208
+ help=_(
209
+ "Image is accessible by all users but does not appear in the "
210
+ "default image list of any user except the owner "
211
+ "(requires --os-image-api-version 2.5 or later)"
212
+ ),
213
+ )
214
+ public_group.add_argument(
215
+ "--shared",
216
+ action="store_const",
217
+ const="shared",
218
+ dest="visibility",
219
+ help=_(
220
+ "Image is only accessible by the owner and image members "
221
+ "(requires --os-image-api-version 2.5 or later) "
222
+ "(default since --os-image-api-version 2.5)"
223
+ ),
224
+ )
225
+
226
+
166
227
  class AddProjectToImage(command.ShowOne):
167
228
  _description = _("Associate project with image")
168
229
 
@@ -322,50 +383,8 @@ class CreateImage(command.ShowOne):
322
383
  "Only use in combination with --sign-key-path"
323
384
  ),
324
385
  )
325
- protected_group = parser.add_mutually_exclusive_group()
326
- protected_group.add_argument(
327
- "--protected",
328
- action="store_true",
329
- dest="is_protected",
330
- default=None,
331
- help=_("Prevent image from being deleted"),
332
- )
333
- protected_group.add_argument(
334
- "--unprotected",
335
- action="store_false",
336
- dest="is_protected",
337
- default=None,
338
- help=_("Allow image to be deleted (default)"),
339
- )
340
- public_group = parser.add_mutually_exclusive_group()
341
- public_group.add_argument(
342
- "--public",
343
- action="store_const",
344
- const="public",
345
- dest="visibility",
346
- help=_("Image is accessible to the public"),
347
- )
348
- public_group.add_argument(
349
- "--private",
350
- action="store_const",
351
- const="private",
352
- dest="visibility",
353
- help=_("Image is inaccessible to the public (default)"),
354
- )
355
- public_group.add_argument(
356
- "--community",
357
- action="store_const",
358
- const="community",
359
- dest="visibility",
360
- help=_("Image is accessible to the community"),
361
- )
362
- public_group.add_argument(
363
- "--shared",
364
- action="store_const",
365
- const="shared",
366
- dest="visibility",
367
- help=_("Image can be shared"),
368
- )
386
+ _add_is_protected_args(parser)
387
+ _add_visibility_args(parser)
369
388
  parser.add_argument(
370
389
  "--property",
371
390
  dest="properties",
@@ -664,7 +683,7 @@ class DeleteImage(command.Command):
664
683
  return parser
665
684
 
666
685
  def take_action(self, parsed_args):
667
- del_result = 0
686
+ result = 0
668
687
  image_client = self.app.client_manager.image
669
688
  for image in parsed_args.images:
670
689
  try:
@@ -672,10 +691,6 @@ class DeleteImage(command.Command):
672
691
  image,
673
692
  ignore_missing=False,
674
693
  )
675
- except sdk_exceptions.ResourceNotFound as e:
676
- msg = _("Unable to process request: %(e)s") % {'e': e}
677
- raise exceptions.CommandError(msg)
678
- try:
679
694
  image_client.delete_image(
680
695
  image_obj.id,
681
696
  store=parsed_args.store,
@@ -685,7 +700,7 @@ class DeleteImage(command.Command):
685
700
  msg = _("Multi Backend support not enabled.")
686
701
  raise exceptions.CommandError(msg)
687
702
  except Exception as e:
688
- del_result += 1
703
+ result += 1
689
704
  msg = _(
690
705
  "Failed to delete image with name or "
691
706
  "ID '%(image)s': %(e)s"
@@ -693,9 +708,9 @@ class DeleteImage(command.Command):
693
708
  LOG.error(msg, {'image': image, 'e': e})
694
709
 
695
710
  total = len(parsed_args.images)
696
- if del_result > 0:
697
- msg = _("Failed to delete %(dresult)s of %(total)s images.") % {
698
- 'dresult': del_result,
711
+ if result > 0:
712
+ msg = _("Failed to delete %(result)s of %(total)s images.") % {
713
+ 'result': result,
699
714
  'total': total,
700
715
  }
701
716
  raise exceptions.CommandError(msg)
@@ -726,14 +741,20 @@ class ListImage(command.Lister):
726
741
  action="store_const",
727
742
  const="community",
728
743
  dest="visibility",
729
- help=_("List only community images"),
744
+ help=_(
745
+ "List only community images "
746
+ "(requires --os-image-api-version 2.5 or later)"
747
+ ),
730
748
  )
731
749
  public_group.add_argument(
732
750
  "--shared",
733
751
  action="store_const",
734
752
  const="shared",
735
753
  dest="visibility",
736
- help=_("List only shared images"),
754
+ help=_(
755
+ "List only shared images "
756
+ "(requires --os-image-api-version 2.5 or later)"
757
+ ),
737
758
  )
738
759
  public_group.add_argument(
739
760
  "--all",
@@ -1110,50 +1131,8 @@ class SetImage(command.Command):
1110
1131
  help=_("Image disk format. The supported options are: %s")
1111
1132
  % ', '.join(DISK_CHOICES),
1112
1133
  )
1113
- protected_group = parser.add_mutually_exclusive_group()
1114
- protected_group.add_argument(
1115
- "--protected",
1116
- action="store_true",
1117
- dest="is_protected",
1118
- default=None,
1119
- help=_("Prevent image from being deleted"),
1120
- )
1121
- protected_group.add_argument(
1122
- "--unprotected",
1123
- action="store_false",
1124
- dest="is_protected",
1125
- default=None,
1126
- help=_("Allow image to be deleted (default)"),
1127
- )
1128
- public_group = parser.add_mutually_exclusive_group()
1129
- public_group.add_argument(
1130
- "--public",
1131
- action="store_const",
1132
- const="public",
1133
- dest="visibility",
1134
- help=_("Image is accessible to the public"),
1135
- )
1136
- public_group.add_argument(
1137
- "--private",
1138
- action="store_const",
1139
- const="private",
1140
- dest="visibility",
1141
- help=_("Image is inaccessible to the public (default)"),
1142
- )
1143
- public_group.add_argument(
1144
- "--community",
1145
- action="store_const",
1146
- const="community",
1147
- dest="visibility",
1148
- help=_("Image is accessible to the community"),
1149
- )
1150
- public_group.add_argument(
1151
- "--shared",
1152
- action="store_const",
1153
- const="shared",
1154
- dest="visibility",
1155
- help=_("Image can be shared"),
1156
- )
1134
+ _add_is_protected_args(parser)
1135
+ _add_visibility_args(parser)
1157
1136
  parser.add_argument(
1158
1137
  "--property",
1159
1138
  dest="properties",
@@ -1814,7 +1793,9 @@ class ImportImage(command.ShowOne):
1814
1793
  )
1815
1794
  raise exceptions.CommandError(msg)
1816
1795
 
1817
- image = image_client.find_image(parsed_args.image)
1796
+ image = image_client.find_image(
1797
+ parsed_args.image, ignore_missing=False
1798
+ )
1818
1799
 
1819
1800
  if not image.container_format and not image.disk_format:
1820
1801
  msg = _(
@@ -187,3 +187,39 @@ class ListMetadefObjects(command.Lister):
187
187
  for md_object in md_objects
188
188
  ),
189
189
  )
190
+
191
+
192
+ class SetMetadefObject(command.Command):
193
+ _description = _("Update a metadef object")
194
+
195
+ def get_parser(self, prog_name):
196
+ parser = super().get_parser(prog_name)
197
+ parser.add_argument(
198
+ "namespace",
199
+ metavar="<namespace>",
200
+ help=_("Metadef namespace name"),
201
+ )
202
+ parser.add_argument(
203
+ "object",
204
+ metavar="<object>",
205
+ help=_('Metadef object to be updated'),
206
+ )
207
+ parser.add_argument(
208
+ "--name",
209
+ help=_("New name of the object"),
210
+ )
211
+ return parser
212
+
213
+ def take_action(self, parsed_args):
214
+ image_client = self.app.client_manager.image
215
+
216
+ object = image_client.get_metadef_object(
217
+ parsed_args.object, parsed_args.namespace
218
+ )
219
+ kwargs = {}
220
+ if parsed_args.name:
221
+ kwargs['name'] = parsed_args.name
222
+
223
+ image_client.update_metadef_object(
224
+ object, parsed_args.namespace, **kwargs
225
+ )
@@ -175,7 +175,7 @@ class DeleteNetworkFlavor(command.Command):
175
175
  )
176
176
  if result > 0:
177
177
  total = len(parsed_args.flavor)
178
- msg = _("%(result)s of %(total)s flavors failed " "to delete.") % {
178
+ msg = _("%(result)s of %(total)s flavors failed to delete.") % {
179
179
  "result": result,
180
180
  "total": total,
181
181
  }
@@ -4965,7 +4965,7 @@ class TestServerList(_TestServerList):
4965
4965
  columns, data = self.cmd.take_action(parsed_args)
4966
4966
 
4967
4967
  self.compute_sdk_client.find_flavor.assert_has_calls(
4968
- [mock.call(self.flavor.id)]
4968
+ [mock.call(self.flavor.id, ignore_missing=False)]
4969
4969
  )
4970
4970
 
4971
4971
  self.kwargs['flavor'] = self.flavor.id
@@ -7119,7 +7119,9 @@ class TestServerRescue(TestServer):
7119
7119
  self.cmd.take_action(parsed_args)
7120
7120
 
7121
7121
  self.servers_mock.get.assert_called_with(self.server.id)
7122
- self.image_client.find_image.assert_called_with(new_image.id)
7122
+ self.image_client.find_image.assert_called_with(
7123
+ new_image.id, ignore_missing=False
7124
+ )
7123
7125
  self.server.rescue.assert_called_with(image=new_image, password=None)
7124
7126
 
7125
7127
  def test_rescue_with_current_image_and_password(self):
@@ -188,7 +188,7 @@ class TestServerGroupDelete(TestServerGroup):
188
188
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
189
189
  result = self.cmd.take_action(parsed_args)
190
190
  self.compute_sdk_client.find_server_group.assert_called_once_with(
191
- 'affinity_group'
191
+ 'affinity_group', ignore_missing=False
192
192
  )
193
193
  self.compute_sdk_client.delete_server_group.assert_called_once_with(
194
194
  self.fake_server_group.id
@@ -203,10 +203,10 @@ class TestServerGroupDelete(TestServerGroup):
203
203
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
204
204
  result = self.cmd.take_action(parsed_args)
205
205
  self.compute_sdk_client.find_server_group.assert_any_call(
206
- 'affinity_group'
206
+ 'affinity_group', ignore_missing=False
207
207
  )
208
208
  self.compute_sdk_client.find_server_group.assert_any_call(
209
- 'anti_affinity_group'
209
+ 'anti_affinity_group', ignore_missing=False
210
210
  )
211
211
  self.compute_sdk_client.delete_server_group.assert_called_with(
212
212
  self.fake_server_group.id
@@ -248,10 +248,10 @@ class TestServerGroupDelete(TestServerGroup):
248
248
  self.assertEqual('1 of 2 server groups failed to delete.', str(e))
249
249
 
250
250
  self.compute_sdk_client.find_server_group.assert_any_call(
251
- 'affinity_group'
251
+ 'affinity_group', ignore_missing=False
252
252
  )
253
253
  self.compute_sdk_client.find_server_group.assert_any_call(
254
- 'anti_affinity_group'
254
+ 'anti_affinity_group', ignore_missing=False
255
255
  )
256
256
  self.assertEqual(
257
257
  2, self.compute_sdk_client.find_server_group.call_count
@@ -141,7 +141,9 @@ class TestListMigration(TestServerMigration):
141
141
  'migration_type': 'migration',
142
142
  }
143
143
 
144
- self.compute_sdk_client.find_server.assert_called_with('server1')
144
+ self.compute_sdk_client.find_server.assert_called_with(
145
+ 'server1', ignore_missing=False
146
+ )
145
147
  self.compute_sdk_client.migrations.assert_called_with(**kwargs)
146
148
 
147
149
  self.assertEqual(self.MIGRATION_COLUMNS, columns)
@@ -731,7 +731,7 @@ class TestImageShow(image_fakes.TestImagev1):
731
731
  # data to be shown.
732
732
  columns, data = self.cmd.take_action(parsed_args)
733
733
  self.image_client.find_image.assert_called_with(
734
- self._image.id,
734
+ self._image.id, ignore_missing=False
735
735
  )
736
736
 
737
737
  self.assertEqual(self.columns, columns)
@@ -753,7 +753,7 @@ class TestImageShow(image_fakes.TestImagev1):
753
753
  # data to be shown.
754
754
  columns, data = self.cmd.take_action(parsed_args)
755
755
  self.image_client.find_image.assert_called_with(
756
- self._image.id,
756
+ self._image.id, ignore_missing=False
757
757
  )
758
758
 
759
759
  size_index = columns.index('size')
@@ -160,3 +160,41 @@ class TestMetadefObjectList(fakes.TestImagev2):
160
160
 
161
161
  self.assertEqual(self.columns, columns)
162
162
  self.assertEqual(getattr(self.datalist[0], 'name'), next(data)[0])
163
+
164
+
165
+ class TestMetadefObjectSet(fakes.TestImagev2):
166
+ _metadef_namespace = fakes.create_one_metadef_namespace()
167
+ _metadef_objects = fakes.create_one_metadef_object()
168
+ new_metadef_object = fakes.create_one_metadef_object(
169
+ attrs={'name': 'new_object_name'}
170
+ )
171
+
172
+ def setUp(self):
173
+ super().setUp()
174
+
175
+ self.image_client.update_metadef_object.return_value = None
176
+ self.cmd = metadef_objects.SetMetadefObject(self.app, None)
177
+
178
+ def test_object_set_no_options(self):
179
+ arglist = [
180
+ self._metadef_namespace.namespace,
181
+ self._metadef_objects.name,
182
+ ]
183
+ verifylist = []
184
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
185
+ result = self.cmd.take_action(parsed_args)
186
+
187
+ self.assertIsNone(result)
188
+
189
+ def test_object_set(self):
190
+ arglist = [
191
+ self._metadef_namespace.namespace,
192
+ self._metadef_objects.name,
193
+ '--name',
194
+ 'new_object_name',
195
+ ]
196
+ verifylist = []
197
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
198
+ result = self.cmd.take_action(parsed_args)
199
+
200
+ self.assertIsNone(result)
@@ -203,10 +203,10 @@ class DeleteVolumeBackup(command.Command):
203
203
  volume_client = self.app.client_manager.sdk_connection.volume
204
204
  result = 0
205
205
 
206
- for i in parsed_args.backups:
206
+ for backup in parsed_args.backups:
207
207
  try:
208
208
  backup_id = volume_client.find_backup(
209
- i, ignore_missing=False
209
+ backup, ignore_missing=False
210
210
  ).id
211
211
  volume_client.delete_backup(
212
212
  backup_id,
@@ -220,7 +220,7 @@ class DeleteVolumeBackup(command.Command):
220
220
  "Failed to delete backup with "
221
221
  "name or ID '%(backup)s': %(e)s"
222
222
  )
223
- % {'backup': i, 'e': e}
223
+ % {'backup': backup, 'e': e}
224
224
  )
225
225
 
226
226
  if result > 0:
@@ -261,6 +261,7 @@ Marek Denis <marek.denis@cern.ch>
261
261
  Mark Vanderwiel <vanderwl@us.ibm.com>
262
262
  Martin Chlumsky <martin.chlumsky@gmail.com>
263
263
  Martin Schuppert <mschuppert@redhat.com>
264
+ Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
264
265
  Masayuki Igawa <masayuki@igawa.io>
265
266
  Matt Fischer <matt@mattfischer.com>
266
267
  Matt Joyce <matt.joyce@cloudscaling.com>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-openstackclient
3
- Version: 6.5.0
3
+ Version: 6.6.1
4
4
  Summary: OpenStack Command-line Client
5
5
  Home-page: https://docs.openstack.org/python-openstackclient/latest/
6
6
  Author: OpenStack
@@ -29,6 +29,7 @@ Requires-Dist: pbr (!=2.1.0,>=2.0.0)
29
29
  Requires-Dist: python-cinderclient (>=3.3.0)
30
30
  Requires-Dist: python-keystoneclient (>=3.22.0)
31
31
  Requires-Dist: python-novaclient (>=18.1.0)
32
+ Requires-Dist: requests (>=2.14.2)
32
33
  Requires-Dist: stevedore (>=2.0.1)
33
34
 
34
35
  ========================
@@ -2,7 +2,7 @@ openstackclient/__init__.py,sha256=80udUgNTRDOEPgCARVgk6BCV0sXWpg1VP9N408GVXiA,7
2
2
  openstackclient/i18n.py,sha256=daSSioNcZ4XxHuw22wSyf6WSz_g8D1tf6d36ghvO6Bw,791
3
3
  openstackclient/shell.py,sha256=BYqdTgiq6VVHiPSc1uT0i00-iWGoh0zsfY1Xm7Q1D6E,5695
4
4
  openstackclient/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- openstackclient/api/api.py,sha256=75eBSbk-31FX0SsdqUiJqidfuFdmGSWF80wxsWxeYqo,9762
5
+ openstackclient/api/api.py,sha256=CuzS6UfP-PktA3Za3KGGrSHZH7S9iKmraJVftN67B4Q,9759
6
6
  openstackclient/api/compute_v2.py,sha256=yFBy3lCrirNIpmmck0Pgwsrb1PEKZoZQSibZ3V0u3cw,16261
7
7
  openstackclient/api/image_v1.py,sha256=7uirFcJzDWeTXIeW41tgkwAmLM5plwIb12AUMXOnDzE,2595
8
8
  openstackclient/api/image_v2.py,sha256=GSM09toS6rcLzbtyhKl_FvQ7UeWJ3EcvSNBdVIk9ryA,2602
@@ -30,12 +30,12 @@ openstackclient/compute/v2/host.py,sha256=N_QsqoISaQhqtKxo1DZhNKe9ZCj42oQ07CPEuI
30
30
  openstackclient/compute/v2/hypervisor.py,sha256=L_qJJe4wsPUoJk3Gb6hMCJFo1kG3vvkupSFpEF9vkJ0,8677
31
31
  openstackclient/compute/v2/hypervisor_stats.py,sha256=Y2Jkkleha8PXnM2VQ2MJtjKxHKchGRyEqmILfPj-Wgw,2161
32
32
  openstackclient/compute/v2/keypair.py,sha256=FLGQMqOkS5suoOdQv7VhW_yNFzq68hnl2RuLxF4egYE,15801
33
- openstackclient/compute/v2/server.py,sha256=5u-Oy0TUEYx3uxmDrpqO6Ryx19Ak_g4pR3Dv2G8xNwo,183463
34
- openstackclient/compute/v2/server_backup.py,sha256=692Wfbu43wAphKsQqOhTmCbw3ZXfmGOMl_SKMPlSszs,4099
33
+ openstackclient/compute/v2/server.py,sha256=CYUFJpFBPkwtSRUeBimlQ1I50ZUv_aDV9LcWmD0oG-I,183547
34
+ openstackclient/compute/v2/server_backup.py,sha256=YnyZh2P7i6bT1ErsKPAxrzb7LyQXVfTpzd-wStbC2f0,4143
35
35
  openstackclient/compute/v2/server_event.py,sha256=vLtu_LBJ99Fgfj9oRBCVATalRMyqBd3CUjHToVfQB48,10055
36
- openstackclient/compute/v2/server_group.py,sha256=IcLsvtUyi9PDmQoVBu1fdH3w1DN21eHGKOZONC-qqMg,8658
36
+ openstackclient/compute/v2/server_group.py,sha256=oS-w-j5LurvJnQbVZ73xND_hJsD28TIv9umRsrGGsIs,8762
37
37
  openstackclient/compute/v2/server_image.py,sha256=U-723wG3xy83GK_c-GAxU5imceT3yBnovKwDxhVlO4o,3889
38
- openstackclient/compute/v2/server_migration.py,sha256=xCaEH_MrHpO5Gi35wrJvkqF7kLVxGCEJRgVzUUZKU8Q,17920
38
+ openstackclient/compute/v2/server_migration.py,sha256=qOgp-G9i1Z3_RosaIu8jCWgBKUlom36bQ2UQzMrq7RU,17816
39
39
  openstackclient/compute/v2/server_volume.py,sha256=S5-bjOTqbdHYKC-oBRs9gSrPU4VXekdxlAOW3tnNL-0,4884
40
40
  openstackclient/compute/v2/service.py,sha256=v3pCOg_yJ3mpcMoVA8xIyyAnjGWqlBOb31aRisceL4U,10874
41
41
  openstackclient/compute/v2/usage.py,sha256=g4HUmk7CfJSRw9vCq5hdLIXswYXRzIvK75kqcLR13kc,9041
@@ -84,13 +84,13 @@ openstackclient/identity/v3/user.py,sha256=TSFVWGALm9hgEXQskigS17ojKfmVyNYZZ9cKa
84
84
  openstackclient/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
85
  openstackclient/image/client.py,sha256=04-B6yBwyzx1BmwvvR_IVNris6_sPlLa3EI-f0Gau_Q,1466
86
86
  openstackclient/image/v1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
- openstackclient/image/v1/image.py,sha256=499Lv0nAPrlAYcon2bsmzxyRQIlzBNHHmDy0A_Bt92E,26223
87
+ openstackclient/image/v1/image.py,sha256=Nz3aav6McYLRoJ1ByMFir9Crd_EQlcndDtZTDT38ohU,27052
88
88
  openstackclient/image/v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
89
  openstackclient/image/v2/cache.py,sha256=YHMYjsCULE8yOibzHoxfHrvYDmgDCUOVfaoRf-hDfkk,6609
90
- openstackclient/image/v2/image.py,sha256=XIgSl0EgOl7bxxxzamWFJn8X_MnU9vkbIIU0CBiKtfE,63539
90
+ openstackclient/image/v2/image.py,sha256=1P1bYPHFXOe4N6HN5gNfnUwKGeMneIZMDqm1e47kktA,62580
91
91
  openstackclient/image/v2/info.py,sha256=ASe4PKVnW4c3o8Pu0d-jVUN_jV9LuU8JBLTDlxnekX8,1089
92
92
  openstackclient/image/v2/metadef_namespaces.py,sha256=CmtsyexMcadacv64ro_8vYUR8gKB0CjuDQViNF5QboQ,9862
93
- openstackclient/image/v2/metadef_objects.py,sha256=fO3YyASgwusO0p6-cBHlpPwHQ0J5lqKuow_W5V78T50,5336
93
+ openstackclient/image/v2/metadef_objects.py,sha256=AZdxZyn-QLQhtyaoyKWf8tHFzh7H6xoX5i3pXcyf-IM,6342
94
94
  openstackclient/image/v2/metadef_properties.py,sha256=SfurkbrneNM2SBr280St0KrcNjUl9iy3XuVOV-slpm8,8382
95
95
  openstackclient/image/v2/metadef_resource_types.py,sha256=AYFigfk2WvW_1cwJU0KsehAgN0no2VRUWjxZEuFrJaA,1265
96
96
  openstackclient/image/v2/task.py,sha256=rh_qqV7xAXanhLUp1x1JRC8g8BIfg5Z0jJ4DGTcIaE4,5083
@@ -114,7 +114,7 @@ openstackclient/network/v2/ndp_proxy.py,sha256=LzoVvcO-yv41v8PIcBPXBvYQbMWgxva1t
114
114
  openstackclient/network/v2/network.py,sha256=fZqvEgdB9I8FVBq_FqH262pf7woaifpG_WFalUXTxTs,29484
115
115
  openstackclient/network/v2/network_agent.py,sha256=M67vl22Sqf0L5PZy9euBLlmSIV4gJa3rgDzimNb5FxA,13699
116
116
  openstackclient/network/v2/network_auto_allocated_topology.py,sha256=JcWcVLVpdwAuyUlaXDB5L1OJ2sufjhzTR5KjPKxQ6NA,4721
117
- openstackclient/network/v2/network_flavor.py,sha256=Jojs9Cwra2x9i0q5zODSB4QEjeJgPa-AsscRDdS5AK0,10083
117
+ openstackclient/network/v2/network_flavor.py,sha256=V38oeyO3TaFn_EmRy--4NyccDRKebrcculJtr1TYbUA,10080
118
118
  openstackclient/network/v2/network_flavor_profile.py,sha256=GCaVbNzOIEEHf92orwJ17Ih_syM8jEkSb1b5qUkGfB0,9151
119
119
  openstackclient/network/v2/network_meter.py,sha256=UnLZs_PeKLAzNQexuGmw9ehG1AC4weW1S_kU6AXAtoI,6193
120
120
  openstackclient/network/v2/network_meter_rule.py,sha256=0k1ukXZYWP6KPbFvP3PEV6Mi-3m9rtGhaD42PWLq_Zo,7778
@@ -291,12 +291,12 @@ openstackclient/tests/unit/compute/v2/test_host.py,sha256=bbh8KrIZuwuf9OpRc9CKmH
291
291
  openstackclient/tests/unit/compute/v2/test_hypervisor.py,sha256=Ah7UOXheOYGLzED1tHqvwvZiWOqf1t2MjlynNFfdH2M,17064
292
292
  openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py,sha256=-XYSaFlNmYMZqtYL0Pmmx2veYLcbST6miSosyrG0MKw,3074
293
293
  openstackclient/tests/unit/compute/v2/test_keypair.py,sha256=1hFP_Ka51Bs7CZVy-uv_la2y1hGtDg8rJjZlwOv4GWg,25821
294
- openstackclient/tests/unit/compute/v2/test_server.py,sha256=k1hMzPzG9SxmdKaIMMYyCOap7PoqCZDqdK3vR9kB66s,294073
294
+ openstackclient/tests/unit/compute/v2/test_server.py,sha256=gEUXVgJ1UdszOLVZQ3L044b0SmESvNi_BZL62vVgQE0,294139
295
295
  openstackclient/tests/unit/compute/v2/test_server_backup.py,sha256=f6yOmL6hkyWHJZue3KPZ8hpDzlx_UWzExvlifKKlh5E,7531
296
296
  openstackclient/tests/unit/compute/v2/test_server_event.py,sha256=BNSR8vaTUOBe3PZAkTSyhR9yFOlV-PzqJRcwwxH2rko,13285
297
- openstackclient/tests/unit/compute/v2/test_server_group.py,sha256=F4BP77t5jHsmxx75kpD_GlzgElGItOuNal-BTefuQvI,15593
297
+ openstackclient/tests/unit/compute/v2/test_server_group.py,sha256=kzg3ykJNxqVV8Qk6TDfU56G7fgxUXGIVQ_hnu7pw-ZI,15703
298
298
  openstackclient/tests/unit/compute/v2/test_server_image.py,sha256=FPL6t0lC6erRSnX_IVl1vLxAYCr4LkffCeeQL6EDk6Y,6910
299
- openstackclient/tests/unit/compute/v2/test_server_migration.py,sha256=vCzbx7CwYIwgBChFi1KGKgSJxeAGyEPByZssi57Zwn4,35811
299
+ openstackclient/tests/unit/compute/v2/test_server_migration.py,sha256=cjVoQ47GcZiG2fyYp5QVk16r2yj7QrYd6Ef5pol94tg,35855
300
300
  openstackclient/tests/unit/compute/v2/test_server_volume.py,sha256=jqtAZjak2RMd3_9dXfrv1_QMYekjTsaLphgBbj0DJ2Y,11773
301
301
  openstackclient/tests/unit/compute/v2/test_service.py,sha256=jWyjGi7yUQ3NPAMpPn0cvpGNt_3gqmaHjv0cIkIonG4,20941
302
302
  openstackclient/tests/unit/compute/v2/test_usage.py,sha256=mZae6MSfSkDjtPiYIrDy5ipKwLAFx2oefZg7xj-0Tuc,6188
@@ -342,14 +342,14 @@ openstackclient/tests/unit/identity/v3/test_user.py,sha256=x3ygpouFIBqQV2ttqH8rK
342
342
  openstackclient/tests/unit/image/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
343
343
  openstackclient/tests/unit/image/v1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
344
344
  openstackclient/tests/unit/image/v1/fakes.py,sha256=rwYSQK12WxSaX2p-f15e6D94qC6lg1XIgBFvdiJ5aRc,2271
345
- openstackclient/tests/unit/image/v1/test_image.py,sha256=sCPIysaQRs9mvkRM_JIIpoFnSsLOJAehfUtqRbytsYI,23761
345
+ openstackclient/tests/unit/image/v1/test_image.py,sha256=-CPk6Vx1G594STaZLNEvvrLOEGghW-5Du46CDFVlj7M,23803
346
346
  openstackclient/tests/unit/image/v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
347
347
  openstackclient/tests/unit/image/v2/fakes.py,sha256=QDjawanbdBbs4_LFeaTbd8bS2TuVEuCoOqCOUQRH9_0,11246
348
348
  openstackclient/tests/unit/image/v2/test_cache.py,sha256=ktfF53jz7DHwCjYsS8f_DZMMsskkI9qKK_7a9fx1nhs,6237
349
349
  openstackclient/tests/unit/image/v2/test_image.py,sha256=2xGkn0e-XdzbriHMPAW_CSpS1azBqfYevCRdtVZB7ww,69065
350
350
  openstackclient/tests/unit/image/v2/test_info.py,sha256=m-eR2YPZ-IcKkLtNabo5Ju_NS75HMpI4rWllvASSVs4,1202
351
351
  openstackclient/tests/unit/image/v2/test_metadef_namespaces.py,sha256=jCA3sMvxxA7f54iVRie1FygZ0Y-_H05cHZa5W3Ntx-Q,5522
352
- openstackclient/tests/unit/image/v2/test_metadef_objects.py,sha256=8W-821JGIEd02gTPRuT01aPXELf1jtQBuGgqXH5bM6I,5167
352
+ openstackclient/tests/unit/image/v2/test_metadef_objects.py,sha256=BxGNFYZwAc2tvwNtkj_sJIQ22NNBqH6X0X8rxx24MEI,6348
353
353
  openstackclient/tests/unit/image/v2/test_metadef_properties.py,sha256=h4TVgYKpJ5ci_L0AqJYQdxi3RqoxAlsymxR_Whm2OJs,6865
354
354
  openstackclient/tests/unit/image/v2/test_metadef_resource_types.py,sha256=h6joEtjWi7gDOrm5mKMMaE8wvNiOrR56SBRr1CddO5k,1483
355
355
  openstackclient/tests/unit/image/v2/test_task.py,sha256=Fe6UR8nRp-YSOkFwMgVJIrhNm1Vq_OPWk-aiivZN1uc,5202
@@ -462,7 +462,7 @@ openstackclient/volume/v2/qos_specs.py,sha256=0ZIgK4SePIcVnR5IXpkoubqKAfCoSTpf4m
462
462
  openstackclient/volume/v2/service.py,sha256=HxGH1x8lJVNcxVemE6Oadrld4DpRo8XEKvqajZa2f8w,4239
463
463
  openstackclient/volume/v2/volume.py,sha256=0iGfQdVMqy7H1xISNidAXrN1CZFGEp_xabcji8i7ueE,33546
464
464
  openstackclient/volume/v2/volume_backend.py,sha256=VsO3hmNzmMUXSocIL4S9cLFZcMOxByx1RmXaTddF9TM,3550
465
- openstackclient/volume/v2/volume_backup.py,sha256=_t1X82qQg22854s1g9B-sgvMAxDKrWMH1MX3ENAjGps,21679
465
+ openstackclient/volume/v2/volume_backup.py,sha256=rtaX0TB9N58deTo8BD6TZvkGJCXzH9nD7BGG-mIdeVQ,21694
466
466
  openstackclient/volume/v2/volume_host.py,sha256=dGsdy1pVV7x-Ofj8Uh65YHnO0quuMsXOu-XNNM5TRAk,2568
467
467
  openstackclient/volume/v2/volume_snapshot.py,sha256=Muy3Q1i7y8ChCBUNZSWUfXMG8Z_GAF2OlGZLSL0ic5A,17022
468
468
  openstackclient/volume/v2/volume_transfer_request.py,sha256=GIWqhOVelfbMBioJK52Y5MqHbOhti4ll9eNBCyehc8k,7661
@@ -479,11 +479,11 @@ openstackclient/volume/v3/volume_group.py,sha256=OQ8ToL0SCCnOFfyOgx-bFNt2N0ZNCkR
479
479
  openstackclient/volume/v3/volume_group_snapshot.py,sha256=sm7B3MSiNYw4eCzoZv8Ko4Y0q_TZ0wVEpqdVblLswEY,6916
480
480
  openstackclient/volume/v3/volume_group_type.py,sha256=ZDQ_MF7CTLj67TvL0rbjo3JVtKdt1czL9jD-nJS1y40,12508
481
481
  openstackclient/volume/v3/volume_message.py,sha256=V-9EKmZESCRDZ4mbXihwOTUTYKk5SZZwri_H2GSBn0s,4937
482
- python_openstackclient-6.5.0.dist-info/AUTHORS,sha256=yVtDnGMAB2kf7yYX_Mh3QEVU7EbTpqacKrWPaGCKpUM,21074
483
- python_openstackclient-6.5.0.dist-info/LICENSE,sha256=XfKg2H1sVi8OoRxoisUlMqoo10TKvHmU_wU39ks7MyA,10143
484
- python_openstackclient-6.5.0.dist-info/METADATA,sha256=ECmoWJJ0KRkcN6NlIrU-WFOj6v5w1e_EoRH2cboBKTE,6539
485
- python_openstackclient-6.5.0.dist-info/WHEEL,sha256=g4nMs7d-Xl9-xC9XovUrsDHGXt-FT0E17Yqo92DEfvY,92
486
- python_openstackclient-6.5.0.dist-info/entry_points.txt,sha256=0-u53_XijcRusLj817peorKThcQAI6DtdXYxKexVgbI,52481
487
- python_openstackclient-6.5.0.dist-info/pbr.json,sha256=UGFOAh70hiz_bdX9y49EfhWfjT49lgzQafIhcWuw4JY,47
488
- python_openstackclient-6.5.0.dist-info/top_level.txt,sha256=htg7z9oZgysRuVUHn-m1Bk6XLGOeV65nMbZX9H8qhs0,16
489
- python_openstackclient-6.5.0.dist-info/RECORD,,
482
+ python_openstackclient-6.6.1.dist-info/AUTHORS,sha256=gc7kKvi86ykx3MAS_xdxf7veisBYJ2gLp0dhXOko0jg,21117
483
+ python_openstackclient-6.6.1.dist-info/LICENSE,sha256=XfKg2H1sVi8OoRxoisUlMqoo10TKvHmU_wU39ks7MyA,10143
484
+ python_openstackclient-6.6.1.dist-info/METADATA,sha256=htv1P2lmHoIw1UTgI2pUyIih2YYvS-FH80_D-JhYiWY,6574
485
+ python_openstackclient-6.6.1.dist-info/WHEEL,sha256=g4nMs7d-Xl9-xC9XovUrsDHGXt-FT0E17Yqo92DEfvY,92
486
+ python_openstackclient-6.6.1.dist-info/entry_points.txt,sha256=eT2sSGcTdC--3CWRz5UV0VMG9wKlR_tCaC7CPN6QPjM,52569
487
+ python_openstackclient-6.6.1.dist-info/pbr.json,sha256=rLJ-sQOAfFOi2iEbcEnDjxBX6y5ruv5Y15Yb5nNJrYk,47
488
+ python_openstackclient-6.6.1.dist-info/top_level.txt,sha256=htg7z9oZgysRuVUHn-m1Bk6XLGOeV65nMbZX9H8qhs0,16
489
+ python_openstackclient-6.6.1.dist-info/RECORD,,
@@ -319,6 +319,7 @@ image_metadef_object_create = openstackclient.image.v2.metadef_objects:CreateMet
319
319
  image_metadef_object_delete = openstackclient.image.v2.metadef_objects:DeleteMetadefObject
320
320
  image_metadef_object_list = openstackclient.image.v2.metadef_objects:ListMetadefObjects
321
321
  image_metadef_object_show = openstackclient.image.v2.metadef_objects:ShowMetadefObjects
322
+ image_metadef_object_update = openstackclient.image.v2.metadef_objects:SetMetadefObject
322
323
  image_metadef_property_create = openstackclient.image.v2.metadef_properties:CreateMetadefProperty
323
324
  image_metadef_property_delete = openstackclient.image.v2.metadef_properties:DeleteMetadefProperty
324
325
  image_metadef_property_list = openstackclient.image.v2.metadef_properties:ListMetadefProperties
@@ -0,0 +1 @@
1
+ {"git_version": "685b7506", "is_release": true}
@@ -1 +0,0 @@
1
- {"git_version": "c29e0576", "is_release": true}