1515import logging
1616
1717from osc_lib import utils
18+ from osc_lib .cli import parseractions
1819from osc_lib .command import command
1920
2021from otcextensions .common import sdk_utils
22+ from otcextensions .common .utils import normalize_tags
2123from otcextensions .i18n import _
2224
2325LOG = logging .getLogger (__name__ )
@@ -28,6 +30,51 @@ def _get_columns(item):
2830 return sdk_utils .get_osc_show_columns_for_sdk_resource (item , column_map )
2931
3032
33+ def _flatten_private_nat_gateway (obj ):
34+ return {
35+ "id" : obj .id ,
36+ "name" : obj .name ,
37+ "description" : obj .description ,
38+ "spec" : obj .spec ,
39+ "project_id" : obj .project_id ,
40+ "enterprise_project_id" : obj .enterprise_project_id ,
41+ "status" : obj .status ,
42+ "created_at" : obj .created_at ,
43+ "updated_at" : obj .updated_at ,
44+ "rule_max" : obj .rule_max ,
45+ "transit_ip_pool_size_max" : obj .transit_ip_pool_size_max ,
46+ }
47+
48+
49+ def _add_downlink_vpcs_to_obj (obj , data , columns ):
50+ for index , downlink_vpc in enumerate (obj .downlink_vpcs or [], start = 1 ):
51+ data += (downlink_vpc .get ("vpc_id" , "" ),)
52+ columns += ("downlink_vpc_id_%s" % index ,)
53+
54+ data += (downlink_vpc .get ("virsubnet_id" , "" ),)
55+ columns += ("downlink_virsubnet_id_%s" % index ,)
56+
57+ data += (downlink_vpc .get ("ngport_ip_address" , "" ),)
58+ columns += ("downlink_ngport_ip_address_%s" % index ,)
59+
60+ return data , columns
61+
62+
63+ def _add_tags_to_obj (obj , data , columns ):
64+ data += (
65+ "\n " .join (
66+ "key=%s, value=%s"
67+ % (
68+ tag .get ("key" , "" ),
69+ tag .get ("value" , "" ),
70+ )
71+ for tag in obj .tags
72+ ),
73+ )
74+ columns += ("tags" ,)
75+ return data , columns
76+
77+
3178class ListPrivateNatGateways (command .Lister ):
3279
3380 _description = _ ("List Private NAT Gateways." )
@@ -177,3 +224,123 @@ def take_action(self, parsed_args):
177224 data = utils .get_item_properties (obj , columns )
178225
179226 return display_columns , data
227+
228+
229+ class CreatePrivateNatGateway (command .ShowOne ):
230+ _description = _ ("Create new Private NAT Gateway" )
231+ columns = (
232+ "id" ,
233+ "name" ,
234+ "description" ,
235+ "spec" ,
236+ "project_id" ,
237+ "enterprise_project_id" ,
238+ "status" ,
239+ "created_at" ,
240+ "updated_at" ,
241+ "rule_max" ,
242+ "transit_ip_pool_size_max" ,
243+ )
244+
245+ def get_parser (self , prog_name ):
246+ parser = super (CreatePrivateNatGateway , self ).get_parser (prog_name )
247+ parser .add_argument (
248+ "--name" ,
249+ metavar = "<name>" ,
250+ required = True ,
251+ help = _ ("Specifies the name of the Private NAT Gateway." ),
252+ )
253+ parser .add_argument (
254+ "--description" ,
255+ metavar = "<description>" ,
256+ help = _ (
257+ "Provides supplementary information about " "the Private NAT Gateway."
258+ ),
259+ )
260+ parser .add_argument (
261+ "--spec" ,
262+ metavar = "<spec>" ,
263+ default = "Small" ,
264+ help = _ (
265+ "Specifies the type of the Private NAT Gateway. "
266+ "The value can be:\n "
267+ "1: small type, which supports up to 10,000 "
268+ "SNAT connections.\n "
269+ "2: medium type, which supports up to 50,000 "
270+ "SNAT connections.\n "
271+ "3: large type, which supports up to 200,000 "
272+ "SNAT connections.\n "
273+ "4: extra-large type, which supports up to "
274+ "1,000,000 SNAT connections."
275+ ),
276+ )
277+ parser .add_argument (
278+ "--enterprise-project-id" ,
279+ metavar = "<enterprise_project_id>" ,
280+ default = 0 ,
281+ help = _ (
282+ "Specifies the ID of the enterprise project"
283+ " that is associated with the private NAT gateway"
284+ " when the private NAT gateway is created."
285+ ),
286+ )
287+ parser .add_argument (
288+ "--downlink-vpc" ,
289+ metavar = "<virsubnet_id=virsubnet_id[,ngport_ip_address=ip]>" ,
290+ action = parseractions .MultiKeyValueAction ,
291+ dest = "downlink_vpcs" ,
292+ required_keys = ["virsubnet_id" ],
293+ optional_keys = ["ngport_ip_address" ],
294+ help = _ ("Specifies the VPC where the private NAT gateway works." ),
295+ )
296+ parser .add_argument (
297+ "--tags" ,
298+ metavar = "<tags>" ,
299+ action = "append" ,
300+ help = _ (
301+ "Specifies the tag list in KEY=VALUE format."
302+ "Repeat for multiple values."
303+ ),
304+ )
305+
306+ return parser
307+
308+ def _build_attrs (self , parsed_args ):
309+ attrs = {
310+ "name" : parsed_args .name ,
311+ "downlink_vpcs" : parsed_args .downlink_vpcs ,
312+ }
313+
314+ optional_attrs = (
315+ "description" ,
316+ "spec" ,
317+ "enterprise_project_id" ,
318+ )
319+ for key in optional_attrs :
320+ value = getattr (parsed_args , key , None )
321+ if value is not None :
322+ attrs [key ] = value
323+
324+ if parsed_args .tags :
325+ attrs ["tags" ] = normalize_tags (parsed_args .tags )
326+
327+ return attrs
328+
329+ def take_action (self , parsed_args ):
330+ client = self .app .client_manager .privatenat
331+
332+ attrs = self ._build_attrs (parsed_args )
333+ obj = client .create_private_nat_gateway (** attrs )
334+
335+ columns = self .columns
336+ data = utils .get_dict_properties (
337+ _flatten_private_nat_gateway (obj ),
338+ columns ,
339+ )
340+
341+ if obj .downlink_vpcs :
342+ data , columns = _add_downlink_vpcs_to_obj (obj , data , columns )
343+ if obj .tags :
344+ data , columns = _add_tags_to_obj (obj , data , columns )
345+
346+ return columns , data
0 commit comments