1515
1616"""Volume v1 Snapshot action implementations"""
1717
18+ import copy
1819import logging
1920import six
20- import sys
2121
2222from cliff import command
2323from cliff import lister
2424from cliff import show
2525
26+ from openstackclient .common import parseractions
2627from 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
0 commit comments