Skip to content

Commit 0170733

Browse files
author
Steve Martinelli
committed
Fix up snapshot command
Several issues with the current snapshot command were resolved: * --long for list was added to include volume id/name, and properties * changed output from metadata to properties * added new option to set properties with 'snapshot set' * added new command to unset properties with 'snapshot unset' Change-Id: I5902cfe876cefada701d4d658a50a4282ff300d6
1 parent 79d0e21 commit 0170733

2 files changed

Lines changed: 116 additions & 14 deletions

File tree

‎openstackclient/volume/v1/snapshot.py‎

Lines changed: 115 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@
1515

1616
"""Volume v1 Snapshot action implementations"""
1717

18+
import copy
1819
import logging
1920
import six
20-
import sys
2121

2222
from cliff import command
2323
from cliff import lister
2424
from cliff import show
2525

26+
from openstackclient.common import parseractions
2627
from openstackclient.common import utils
2728

2829

@@ -70,6 +71,10 @@ def take_action(self, parsed_args):
7071
parsed_args.description
7172
)
7273

74+
snapshot._info.update(
75+
{'properties': utils.format_dict(snapshot._info.pop('metadata'))}
76+
)
77+
7378
return zip(*sorted(six.iteritems(snapshot._info)))
7479

7580

@@ -103,20 +108,61 @@ class ListSnapshot(lister.Lister):
103108

104109
log = logging.getLogger(__name__ + '.ListSnapshot')
105110

111+
def get_parser(self, prog_name):
112+
parser = super(ListSnapshot, self).get_parser(prog_name)
113+
parser.add_argument(
114+
'--long',
115+
action='store_true',
116+
default=False,
117+
help='List additional fields in output',
118+
)
119+
return parser
120+
106121
def take_action(self, parsed_args):
107122
self.log.debug('take_action(%s)', parsed_args)
108-
columns = (
109-
'ID',
110-
'Display Name',
111-
'Display Description',
112-
'Status',
113-
'Size'
114-
)
123+
124+
def _format_volume_id(volume_id):
125+
"""Return a volume name if available
126+
127+
:param volume_id: a volume ID
128+
:rtype: either the volume ID or name
129+
"""
130+
131+
volume = volume_id
132+
if volume_id in volume_cache.keys():
133+
volume = volume_cache[volume_id].display_name
134+
return volume
135+
136+
if parsed_args.long:
137+
columns = ['ID', 'Display Name', 'Display Description', 'Status',
138+
'Size', 'Created At', 'Volume ID', 'Metadata']
139+
column_headers = copy.deepcopy(columns)
140+
column_headers[6] = 'Volume'
141+
column_headers[7] = 'Properties'
142+
else:
143+
columns = ['ID', 'Display Name', 'Display Description', 'Status',
144+
'Size']
145+
column_headers = copy.deepcopy(columns)
146+
147+
# Always update Name and Description
148+
column_headers[1] = 'Name'
149+
column_headers[2] = 'Description'
150+
151+
# Cache the volume list
152+
volume_cache = {}
153+
try:
154+
for s in self.app.client_manager.volume.volumes.list():
155+
volume_cache[s.id] = s
156+
except Exception:
157+
# Just forget it if there's any trouble
158+
pass
159+
115160
data = self.app.client_manager.volume.volume_snapshots.list()
116-
return (columns,
161+
return (column_headers,
117162
(utils.get_item_properties(
118163
s, columns,
119-
formatters={},
164+
formatters={'Metadata': utils.format_dict,
165+
'Volume ID': _format_volume_id},
120166
) for s in data))
121167

122168

@@ -133,28 +179,41 @@ def get_parser(self, prog_name):
133179
help='Name or ID of snapshot to change')
134180
parser.add_argument(
135181
'--name',
136-
metavar='<new-snapshot-name>',
182+
metavar='<snapshot-name>',
137183
help='New snapshot name')
138184
parser.add_argument(
139185
'--description',
140-
metavar='<new-snapshot-description>',
186+
metavar='<snapshot-description>',
141187
help='New snapshot description')
188+
parser.add_argument(
189+
'--property',
190+
metavar='<key=value>',
191+
action=parseractions.KeyValueAction,
192+
help='Property to add/change for this snapshot '
193+
'(repeat option to set multiple properties)',
194+
)
142195
return parser
143196

144197
def take_action(self, parsed_args):
145198
self.log.debug('take_action(%s)', parsed_args)
146199
volume_client = self.app.client_manager.volume
147200
snapshot = utils.find_resource(volume_client.volume_snapshots,
148201
parsed_args.snapshot)
202+
203+
if parsed_args.property:
204+
volume_client.volume_snapshots.set_metadata(snapshot.id,
205+
parsed_args.property)
206+
149207
kwargs = {}
150208
if parsed_args.name:
151209
kwargs['display_name'] = parsed_args.name
152210
if parsed_args.description:
153211
kwargs['display_description'] = parsed_args.description
154212

155-
if not kwargs:
156-
sys.stdout.write("Snapshot not updated, no arguments present")
213+
if not kwargs and not parsed_args.property:
214+
self.app.log.error("No changes requested\n")
157215
return
216+
158217
snapshot.update(**kwargs)
159218
return
160219

@@ -178,4 +237,46 @@ def take_action(self, parsed_args):
178237
snapshot = utils.find_resource(volume_client.volume_snapshots,
179238
parsed_args.snapshot)
180239

240+
snapshot._info.update(
241+
{'properties': utils.format_dict(snapshot._info.pop('metadata'))}
242+
)
243+
181244
return zip(*sorted(six.iteritems(snapshot._info)))
245+
246+
247+
class UnsetSnapshot(command.Command):
248+
"""Unset snapshot properties"""
249+
250+
log = logging.getLogger(__name__ + '.UnsetSnapshot')
251+
252+
def get_parser(self, prog_name):
253+
parser = super(UnsetSnapshot, self).get_parser(prog_name)
254+
parser.add_argument(
255+
'snapshot',
256+
metavar='<snapshot>',
257+
help='snapshot to change (name or ID)',
258+
)
259+
parser.add_argument(
260+
'--property',
261+
metavar='<key>',
262+
action='append',
263+
default=[],
264+
help='Property key to remove from snapshot '
265+
'(repeat to remove multiple values)',
266+
)
267+
return parser
268+
269+
def take_action(self, parsed_args):
270+
self.log.debug('take_action(%s)', parsed_args)
271+
volume_client = self.app.client_manager.volume
272+
snapshot = utils.find_resource(
273+
volume_client.volume_snapshots, parsed_args.snapshot)
274+
275+
if parsed_args.property:
276+
volume_client.volume_snapshots.delete_metadata(
277+
snapshot.id,
278+
parsed_args.property,
279+
)
280+
else:
281+
self.app.log.error("No changes requested\n")
282+
return

‎setup.cfg‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ openstack.volume.v1 =
326326
snapshot_list = openstackclient.volume.v1.snapshot:ListSnapshot
327327
snapshot_set = openstackclient.volume.v1.snapshot:SetSnapshot
328328
snapshot_show = openstackclient.volume.v1.snapshot:ShowSnapshot
329+
snapshot_unset = openstackclient.volume.v1.snapshot:UnsetSnapshot
329330

330331
volume_create = openstackclient.volume.v1.volume:CreateVolume
331332
volume_delete = openstackclient.volume.v1.volume:DeleteVolume

0 commit comments

Comments
 (0)