@@ -21,8 +21,8 @@ if (sys.platform != "win32"):
2121 import fcntl
2222import errno
2323import datetime
24- VERSION = "1.7 "
25- UPDATED = "2023-05-02 "
24+ VERSION = "1.8 "
25+ UPDATED = "2023-06-12 "
2626
2727# ==============================================================================
2828# Global variables
@@ -57,7 +57,6 @@ default_out_spec = 'name{:.30}#shape#cidr-block#prohibit-public{:5.5}' \
5757 '#token'
5858
5959matches = [] # list of commands that match user input
60- best_match = None # matches[best_match] is the closest match
6160all_options_for_this_cmd = '' # for best_match
6261remaining_options = '' # for best_match
6362options_out = [] # list of expanded options to be passed to oci cli
@@ -91,11 +90,13 @@ def usage(s=''):
9190 <oci-options> Options and parameters for <oci-command>
9291 These will be expanded into a more correct oci command
9392
94- . or go Run the oci command if the line ends with "." (or "go")""" )
93+ . or go If the line ends with "." (or "go") run the oci command
94+ ! If line ends with "!", force-run the command, even if
95+ param substitution fails""" )
9596
9697 if s != "help" :
9798 print ("""
98- o help More "o" options. Use "--help ." to get oci help """ )
99+ o help More "o" options and usage. """ )
99100 else :
100101 print ("""
101102 More output options:
@@ -122,7 +123,15 @@ def usage(s=''):
122123
123124 o prune "name" Remove OCIDs for resources matching "name" from
124125 $HOME/.oci/ocids. If "name" is a compartment, remove
125- all OCIDS under compartment "name".""" )
126+ all OCIDS under compartment "name".
127+
128+ touch $HOME/.oci/.otmp Activate "save last result" feature. With this
129+ you can reformat output from the last command
130+ without re-running the command with:
131+ o -o <fmt>
132+
133+ o <oci-command> help Show all parameters, including globals
134+ o <oci-command> --help . Get help from oci""" )
126135 print ("""
127136 o Version {} - {}
128137 """ .format (VERSION , UPDATED ))
@@ -271,10 +280,9 @@ def setup_ocids_file():
271280
272281and I'll do this for you:
273282
274- o iam compartment get -c <tenancy-ocid> go
275- o iam ad list -c <tenancy-ocid> go
276- o iam region list go
277- o iam compartment list -c <tenancy-ocid> -ciis true -all go
283+ o iam compartment list -c <tenancy-ocid> -ciis true -all .
284+ o iam ad list -c <tenancy-ocid> .
285+ o iam region-subscription list .
278286 """ )
279287
280288 # To be extra helpful, get likely tenancy ocid from oci config file
@@ -293,23 +301,30 @@ and I'll do this for you:
293301 if len (sys .argv ) == 3 :
294302 print ("Tenancy name:" , sys .argv [2 ])
295303 print (bold ('Setting up your ' + ocids_file_name + ' file:' ))
296- if run_command (sys .argv [0 ] + ' -o name iam compartment get -c ' + sys .argv [1 ] + ' go' ):
304+ print (bold ('\n Getting compartment names and ocids...' ), end = '' )
305+ if run_command (sys .argv [0 ] + ' -o name iam compartment list -c ' + sys .argv [1 ] + ' -ciis true -all .' ):
306+ print ('\n That didn\' t work. Your account may need additional privileges.' )
307+ exit (0 )
308+ print (bold ('\n Getting availability domains...' ), end = '' )
309+ run_command (sys .argv [0 ] + ' -o name iam ad list -c ' + sys .argv [1 ] + ' .' )
310+ print (bold ('\n Getting regions...' ), end = '' )
311+ run_command (sys .argv [0 ] + ' -o name iam region-subscription list .' )
312+ print (bold ('\n Getting tenancy name from root compartment...' ), end = '' )
313+ if run_command (sys .argv [0 ] + ' -o name iam compartment get -c ' + sys .argv [1 ] + ' .' ):
297314 # compartment get on tenancy failed; try saving a stub for tenancy
298- print ("\n That didn't work. Creating a stub for tenancy root." )
315+ print ("\n Could not get root compartment." )
316+ tenancy_name = input (bold ("Enter tenancy name: " ))
317+ if not tenancy_name :
318+ tenancy_name = 'root'
299319 newids = {'root' : {
300320 'type' : 'tenancy' ,
301- 'alias' : 'root' if len (sys .argv ) == 2
302- else sys .argv [2 ],
321+ 'alias' : tenancy_name ,
303322 'id' : sys .argv [1 ],
304- 'name' : 'root' if len ( sys . argv ) == 2 else sys . argv [ 2 ]
323+ 'name' : tenancy_name ,
305324 },
306325 }
307326 ocids_file ('write' , newids )
308327 exit (0 )
309- run_command (sys .argv [0 ] + ' -o name iam ad list -c ' + sys .argv [1 ] + ' go' )
310- run_command (sys .argv [0 ] + ' -o name iam region list go' )
311- run_command (sys .argv [0 ] + ' -o name iam compartment list -c '
312- + sys .argv [1 ] + ' -ciis true -all go' )
313328 print ('\n ' + bold ('All set. Have fun!\n ' ))
314329
315330 exit (0 )
@@ -342,7 +357,7 @@ def ocids_file(action, new_ocids={}):
342357 # Run setup if no ocids_file exists or
343358 # if this is an "o <tenancy>" setup command and new_ocids is empty
344359 if (not new_ocids
345- and (not re .search ('get .*-c ocid..tenancy' , ' ' .join (sys .argv ))
360+ and (not ( re .search ('iam compartment list .*-c ocid..tenancy' , ' ' .join (sys .argv ) ))
346361 and (not os .path .exists (ocids_file_name )
347362 or re .search ('o [^c]*ocid..tenancy' , ' ' .join (sys .argv ))))):
348363 setup_ocids_file ()
@@ -570,10 +585,8 @@ def args_match_command(c, params):
570585 # accept plurals in place of singulars
571586 if (len (a ) > 3 and a [- 1 ] == 's' and a not in ['address' , 'access' , 'waas' ]):
572587 a = a [:- 1 ]
573-
574- # stop searching at first -opt
575- if (len (a ) and a [0 ] == '-' ):
576- return (True )
588+ if a [- 2 :] == 'ie' :
589+ a = a [:- 2 ]
577590
578591 # Look for full-word match first
579592 if ' ' + a + ' ' in action :
@@ -584,7 +597,7 @@ def args_match_command(c, params):
584597 # look for word starting with arg
585598 if ' ' + a in action or '-' + a in action :
586599 # Scratch out this match
587- action = re .sub (' ' + a + r'\S+' , ' ' , action , count = 1 )
600+ action = re .sub (' ' + r'(\S+-)*' + a + r'( \S+) ' , ' ' , action , count = 1 )
588601 continue
589602
590603 # look for rlc -> really-long-command
@@ -1163,7 +1176,7 @@ def jdump_item(item, indent=2):
11631176 re .sub (r'(?m)^[\s{}[\],]+\n' , '' , # noqa: E128
11641177 # noqa: E128 change key: [ value ] -> key: value
11651178 re .sub (r': \[\s+("[^"]*")\s+]' , r': \1' , # noqa: E128
1166- json .dumps (item , indent = indent ))))))) # noqa: E128
1179+ json .dumps (item , indent = indent , ensure_ascii = False ))))))) # noqa: E128
11671180
11681181# ==============================================================================
11691182
@@ -1212,7 +1225,7 @@ def show_item(item, fields, sep):
12121225 else :
12131226 out .append (value )
12141227 else :
1215- if field == 'id' and sep == '|' and user_out_spec == default_out_spec :
1228+ if field == 'id' and sep == '|' and user_out_spec == default_out_spec and 'ocid' in value :
12161229 out .append (' ' + value .split ('.' )[3 ])
12171230 out .append (column [field ]['format' ].format (re .sub (r'[{}\'[\]\n]' , '' , value )[
12181231 column [field ]['offset' ]:]))
@@ -1959,20 +1972,19 @@ elif 'help' == CLI_params[-1]:
19591972# ==============================================================================
19601973# Identify matching oci cli command(s)
19611974# ==============================================================================
1962- options_in_args = any (len (i ) > 0 and '-' in i [0 ] for i in CLI_params )
1975+ command_words = [i for i , w in enumerate (CLI_params ) if w .startswith ('-' )]
1976+ ncw = command_words [0 ] if command_words else len (CLI_params )
1977+ options_in_args = len (command_words ) > 0
19631978
1964- # Prioritize core services above others. The list could include: os, fs, bv
1965- # But these already have priority due to their short service names.
1966- # Each service name must end with ' '.
1967- priority_services = ('compute ' , 'bv ' , 'os ' , 'network ' , 'iam ' )
1979+ # Prioritize core services above others.
1980+ priority_services = ('compute ' , 'bv ' , 'os ' , 'network ' , 'iam ' , 'db ' )
19681981
19691982# Find matching commands. Sort by priority, then by command length.
1970- matches = sorted ([c for c in command if args_match_command (c , CLI_params )],
1983+ matches = sorted ([c for c in command if args_match_command (c , CLI_params [: ncw ] )],
19711984 key = lambda c : (len (c ['action' ]) if len (c ['action' ]) < 25 else int (round (len (c ['action' ]) / 10. ) * 10. ))
19721985 if c ['action' ].startswith (priority_services )
19731986 else (1.5 * len (c ['action' ]) if len (c ['action' ]) < 25 else 1.5 * int (round (len (c ['action' ]) / 10. ) * 10. )),
19741987 reverse = True )
1975- best_match = len (matches ) - 1
19761988
19771989# ==============================================================================
19781990# Take action - either show help or 'go' run the command
@@ -1982,8 +1994,8 @@ if len(matches) == 0:
19821994 + '\n \n Try: o .' )
19831995
19841996# If many matches, list matches and exit
1985- elif not (len (matches ) <= 16 or ( 'db' in CLI_params and len ( matches ) <= 50 )
1986- or matches [best_match ]['action' ].split (' ' )[0 ] + ' ' in priority_services ):
1997+ elif not (len (matches ) <= 16
1998+ or ( matches [- 1 ]['action' ].split (' ' )[0 ] + ' ' in priority_services and len ( matches ) < 200 and ncw > 1 ) ):
19871999 print (bold ('Possible commands:' ))
19882000 for c in matches :
19892001 show_command (c , prefix = ' ' )
@@ -1994,28 +2006,30 @@ elif not (len(matches) <= 16 or ('db' in CLI_params and len(matches) <= 50)
19942006elif show_help :
19952007 for c in matches :
19962008 show_command (c , full = True )
1997- print ('use:' , bold ('o ' + c ['action' ] + ' --help go' ), 'for full oci help' )
2009+ print ('For oci help:' , bold ('o ' + c ['action' ] + ' --help .\n ' )
2010+ + 'https://docs.oracle.com/en-us/iaas/tools/oci-cli/latest/oci_cli_docs/cmdref/'
2011+ + c ['action' ].replace (' ' , '/' ) + '.html' )
19982012 exit (0 )
19992013
20002014# Fewer than 16 matches. Didn't ask for help.
20012015elif not go and quiet < 1 :
20022016 if len (matches ) > 1 :
20032017 if options_in_args :
2004- print (bold (str (len (matches )) + ' other matching commands not shown.'
2018+ print (bold (str (len (matches ) - 1 ) + ' other matching commands not shown.'
20052019 + ' (Remove parameters to see other commands.)' ), end = '' )
20062020 else :
20072021 print (bold ('Possible matches:' ))
20082022 for i in range (len (matches )):
2009- if i != best_match :
2023+ if i != len ( matches ) - 1 :
20102024 show_command (matches [i ], prefix = ' ' )
20112025 print (bold ('\n Best match:' ))
2012- show_command (matches [best_match ], full = True )
2026+ show_command (matches [- 1 ], full = True )
20132027
20142028# ==============================================================================
2015- # We've settled on matching_command[best_match] .
2029+ # We've settled on matches[-1] as the best match .
20162030# Continue interpreting additional parameters (even if no 'go')
20172031# ==============================================================================
2018- c = matches [best_match ]
2032+ c = matches [- 1 ]
20192033oci_command_line = 'oci ' + c ['action' ] + ' '
20202034
20212035if c ['action' ] in ('audit event list' , 'logging-search search-logs' ) and \
0 commit comments