Skip to content

Commit a93e09d

Browse files
authored
Releasing version 3.23.0
Releasing version 3.23.0
2 parents 8632b18 + e7dcba5 commit a93e09d

File tree

82 files changed

+76117
-393
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+76117
-393
lines changed

CHANGELOG.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,33 @@ All notable changes to this project will be documented in this file.
66

77
The format is based on `Keep a Changelog <http://keepachangelog.com/>`__.
88

9+
3.23.0 - 2023-02-14
10+
--------------------
11+
Added
12+
~~~~~
13+
* Support for the Autonomous Recovery Service
14+
15+
* ``oci recovery``
16+
17+
* Support for the Visual Builder Studio service
18+
19+
* ``oci vbstudio``
20+
21+
* Added support for selecting DBServers while creating Autonomous VM Cluster in Database service
22+
23+
* ``oci db autonomous-virtual-machine get --autonomous-virtual-machine-id``
24+
* ``oci db autonomous-virtual-machine list --autonomous-vm-cluster-id, --compartment-id``
25+
26+
Changed
27+
~~~~~~~
28+
* [BREAKING] Support for a new Capacity Availability API in the Compute service
29+
30+
* ``oci compute computecapacityreport update``
31+
32+
* Modified existing commands in Database service
33+
34+
* ``oci db autonomous-vm-cluster create --db-servers``
35+
936
3.22.5 - 2023-02-07
1037
--------------------
1138
Added

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Jinja2==3.0.3
1414
jmespath==0.10.0
1515
ndg-httpsclient==0.4.2
1616
mock==2.0.0
17-
oci==2.91.0
17+
oci==2.92.0
1818
packaging==20.2
1919
pluggy==0.13.0
2020
py==1.10.0

scripts/examples/project_o/README.md

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,18 @@ Public Subnet VLKn:US-ASHBURN-AD-1 AVAILABLE 10.0.0.0/24 sales
4747
```
4848
**``o``** default output is a table of commonly useful fields, but **``o``** makes it easy to pick just what you want (as seen in the above example).
4949

50+
## Installation
51+
52+
**``o``** is a single file. To install, download **``o``**, place it in your PATH (probably in the same place as ``oci``), and make it executable.
53+
**``o``** works in Linux, Mac, WSL and CloudShell.
54+
55+
Use these commands to get ``o`` from github and install it next to ``oci``.
56+
```
57+
o_src=https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/examples/project_o/o
58+
where=$(which oci) && to=${where%ci} && wget -q $o_src -O $to && chmod a+x $to
59+
```
60+
When you first run `o` it will tell you how to create the commands file *$HOME/.oci/oci_commands*, and then `o` helps you to initialize your *$HOME/.oci/ocids* file.
61+
5062
## Things you can do with ``o``
5163

5264
- find the desired `oci` command from thousands of possible commands
@@ -106,18 +118,12 @@ Public Subnet VLKn:US-ASHBURN-AD-1 AVAILABLE 10.0.0.0/24 sales
106118
- `o -o id:-.10#name:6#create:.10 comp inst list`
107119
- table output with right-most 10 characters of `id`, `display-name` in 6 (or more) characters, and first 10 characters of `time-created`
108120

109-
110-
## Installation
111-
112-
**``o``** is a single file. To install, download **``o``**, place it in your PATH (probably in the same place as ``oci``), and make it executable.
113-
**``o``** works in Linux, Mac, WSL and CloudShell.
114-
115-
Use these commands to get ``o`` from github and install it next to ``oci``.
116-
```
117-
o_src=https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/examples/project_o/o
118-
where=$(which oci) && to=${where%ci} && wget -q $o_src -O $to && chmod a+x $to
119-
```
120-
When you first run `o` it will tell you how to create the commands file *$HOME/.oci/oci_commands*, and then `o` helps you to initialize your *$HOME/.oci/ocids* file.
121+
#### New in version 1.5 (2023-02-07)
122+
- show additional output fields (not in "data") like object storage "prefixes"
123+
- Keep default output fields and
124+
- change format style with separator: `-o +/`
125+
- append additional fields: `-o +new#fields`
126+
- change format and append: `-o +new/fields`
121127

122128
## How **``o``** works
123129
- **``o``** compares your input with thousands of ``oci`` commands, and uses an fuzzy matching to find the command you want.

scripts/examples/project_o/o

Lines changed: 84 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import os
2020
import fcntl
2121
import errno
2222
import datetime
23-
VERSION = "1.4"
24-
UPDATED = "2023-01-20"
23+
VERSION = "1.5"
24+
UPDATED = "2023-02-07"
2525

2626
# ==============================================================================
2727
# Global variables
@@ -863,7 +863,9 @@ def get_matching_ocid(option, value):
863863
opt_type = 'credential'
864864
elif opt_type == 'zonenameor':
865865
opt_type = 'dns-zone'
866-
# print('HERE opt_type', opt_type)
866+
elif opt_type == 'identityprovider':
867+
opt_type = 'saml2idp'
868+
# Add new idtypes to the above when the --whatever-id does not match ocid1.whatevs...
867869

868870
matches = [item for k, item in ocid.items() if
869871
type_match(opt_type, item['type'])
@@ -1012,11 +1014,11 @@ def get_fields_from(spec, keynames):
10121014
if not keynames:
10131015
return fields, sep # show all fields
10141016

1015-
specs = spec.split(sep if sep != ' ' else None)
1017+
specs = spec.split(sep)
10161018

10171019
if sep == r'#':
10181020
sep = '|'
1019-
if not specs[-1]:
1021+
if specs and not specs[-1]:
10201022
specs.pop(-1) # remove empty spec
10211023

10221024
for sf in specs:
@@ -1038,8 +1040,8 @@ def get_fields_from(spec, keynames):
10381040
# Search for partial keyname matches
10391041
sf = s.split('.')
10401042
for k in sorted(keynames):
1041-
if (user_out_spec == default_out_spec and (
1042-
k == 'quota-names'
1043+
if (len(user_out_spec) >= len(default_out_spec) and (
1044+
s == 'name' and k == 'quota-names'
10431045
or s == 'size' and 'resize' in k
10441046
or s == 'id' and 'bandwidth' in k
10451047
or s == 'id' and 'identity' in k)):
@@ -1126,17 +1128,18 @@ def show_column_headers(out_fields, sep):
11261128
# ==============================================================================
11271129

11281130

1129-
def jdump_item(item):
1131+
def jdump_item(item, indent=2):
11301132
"""Remove json decorations, empty lines from json.dumps output"""
11311133

11321134
return (re.sub(r'(?m)"\s*$|( *)"', r'\1', # remove outer double-quotes
1133-
# remove closing braces and trailing newline
1135+
re.sub(r'^\["', '"', # remove braces
1136+
# noqa: E128 remove closing braces and trailing newline
11341137
re.sub(r'(?m)[\[\]{},]+$', '', # noqa: E128
11351138
# noqa: E128 remove braces at beginning of lines, empty lines
11361139
re.sub(r'(?m)^[\s{}[\],]+\n', '', # noqa: E128
11371140
# noqa: E128 change key: [ value ] -> key: value
11381141
re.sub(r': \[\s+("[^"]*")\s+]', r': \1', # noqa: E128
1139-
json.dumps(item, indent=2)))))) # noqa: E128
1142+
json.dumps(item, indent=indent))))))) # noqa: E128
11401143

11411144
# ==============================================================================
11421145

@@ -1188,7 +1191,6 @@ def show_item(item, fields, sep):
11881191
if k == 'access-uri':
11891192
print(column['keyfmt'].format(k) + ' ' + value)
11901193
elif '\n' in value:
1191-
# value = re.sub(r'(,){0,1}\n ', '\n' + ' ' * (maxkeylen + 3), value)
11921194
value = re.sub(r'\n ', '\n' + ' ' * (maxkeylen + 3), value)
11931195
value = re.sub(r'$\n', '', value)
11941196
value = re.sub(r'^ ', '', re.sub('\n ', '\n', value))
@@ -1237,12 +1239,22 @@ def get_key_list(items, prefix=''):
12371239

12381240

12391241
def output(jsonOut):
1242+
"""Send formatted output from oci command to stdout.
1243+
1244+
jsonOut is the json returned by oci.
1245+
Possible JSON 'data' returns:
1246+
get: {'data': {'compartment-id': 'ocid1.compartment.oc1..aaa...
1247+
list: {'data': [{'compartment-id': 'ocid1.compartment.oc1..aaid7...
1248+
ns get: { "data": "mytenancyname" }
1249+
service-connector list: {'data': { 'items': [ ]}}
1250+
The useful payload usually is in "data", but could be a string, dict,
1251+
list of dicts, etc.
1252+
1253+
Format payload according to the "-o spec" and print to stdout.
1254+
Show any additional non-"data" key-values, unless quiet.
1255+
"""
1256+
12401257
if type(jsonOut) is dict and 'data' in jsonOut:
1241-
# Possible JSON 'data' returns:
1242-
# get: {'data': {'compartment-id': 'ocid1.compartment.oc1..aaa...
1243-
# list: {'data': [{'compartment-id': 'ocid1.compartment.oc1..aaid7...
1244-
# ns get: { "data": "mytenancyname" }
1245-
# service-connector list: {'data': { 'items': [ ]}}
12461258
# copy the returned 'data' into results list
12471259
if type(jsonOut['data']) is list:
12481260
results = jsonOut['data']
@@ -1259,7 +1271,7 @@ def output(jsonOut):
12591271
except (KeyError, IndexError):
12601272
results = [jsonOut]
12611273
else:
1262-
results = [jsonOut] # sloppy
1274+
results = [jsonOut]
12631275

12641276
elif type(jsonOut) is list and type(jsonOut[0]) is dict:
12651277
# Other JSON outputs:
@@ -1273,6 +1285,11 @@ def output(jsonOut):
12731285
# It's JSON, but I don't understand its format.
12741286
return 1
12751287

1288+
# ==========================================================================
1289+
# Above we filled results[] with data.
1290+
# Below we format and display the data.
1291+
# ==========================================================================
1292+
12761293
if not user_out_spec:
12771294
print(json.dumps(jsonOut, indent=4))
12781295
return results
@@ -1292,14 +1309,29 @@ def output(jsonOut):
12921309
show_column_headers(out_fields, out_sep)
12931310
for item in results:
12941311
show_item(item, out_fields, out_sep)
1295-
if type(jsonOut) is dict and 'opc-next-page' in jsonOut:
1296-
if not quiet:
1297-
print(bold("\nFor next page: --page next"), file=sys.stderr)
1298-
# Append opc-next-page to results
1299-
results.append({"type": "",
1300-
"alias": "opc-next-page",
1301-
"name": "opc-next-page",
1302-
"id": jsonOut['opc-next-page']})
1312+
1313+
# Any extra non-'data' key-values? Send to stdout
1314+
if type(jsonOut) is dict and jsonOut.keys() != ['data']:
1315+
kmax = str(max([len(str(k)) for k in jsonOut]))
1316+
kfmt = '{:>' + kmax + '.' + kmax + '}'
1317+
nondata = '\n'
1318+
for k in jsonOut:
1319+
if k == 'opc-next-page':
1320+
# Save opc-next-page to ocids file
1321+
results.append({"type": "",
1322+
"alias": "opc-next-page",
1323+
"name": "opc-next-page",
1324+
"id": jsonOut['opc-next-page']})
1325+
nondata += 'For next page: --page next\n'
1326+
elif not quiet and k != 'data' and jsonOut[k]:
1327+
nondata += kfmt.format(k) + ' '
1328+
if type(jsonOut[k]) is str:
1329+
nondata += jsonOut[k] + '\n'
1330+
else:
1331+
nondata += jdump_item(jsonOut[k], None) + '\n'
1332+
if not quiet and nondata > '\n':
1333+
print(bold(nondata), file=sys.stdout)
1334+
13031335
return results
13041336

13051337
# ==============================================================================
@@ -1668,7 +1700,8 @@ def get_oci_commands(argv):
16681700

16691701
# o oci_commands - no service name; get commands for all services
16701702
if len(sys.argv) == 2:
1671-
sp = subprocess.run(['oci', '--help'], capture_output=True)
1703+
sp = subprocess.run(['oci', '--help'], stdout=subprocess.PIPE,
1704+
stderr=subprocess.PIPE)
16721705
out = sp.stdout.decode('utf-8')
16731706
part1 = re.sub(r'.*Options:\n|Commands:\n.*', '', out, flags=re.S)
16741707
globals = sorted(list(dict.fromkeys(re.findall(r'--[A-Za-z-]*', part1))))
@@ -1692,7 +1725,8 @@ def get_oci_commands(argv):
16921725
exit(0)
16931726

16941727
# o oci_commands <service>
1695-
sp = subprocess.run(['oci'] + sys.argv[2:] + ['--help'], capture_output=True)
1728+
sp = subprocess.run(['oci'] + sys.argv[2:] + ['--help'],
1729+
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
16961730
out = sp.stdout.decode('utf-8')
16971731

16981732
if out.startswith('Usage'):
@@ -1822,10 +1856,29 @@ if '-i' in opts:
18221856
user_in_spec = [v for o, v in optvals if o == '-i'][0]
18231857
if '-o' in opts:
18241858
user_out_spec = [v for o, v in optvals if o == '-o'][0]
1825-
if user_out_spec in ['json', 'JSON']:
1859+
if user_out_spec.lower() in ['json', 'j']:
18261860
user_out_spec = ''
1827-
elif user_out_spec in ['text', 'raw']:
1861+
elif user_out_spec.lower() in ['text', 'raw']:
18281862
user_out_spec = '/'
1863+
elif user_out_spec[0] in '+/,#\t ':
1864+
# if user spec starts with + or separator, append spec to defaults
1865+
# if user spec is bare separator, show all fields
1866+
# if spec contains a separator, use separator and user spec
1867+
sep = '#'
1868+
spec = user_out_spec
1869+
if spec[0] == '+':
1870+
spec = user_out_spec[1:]
1871+
if spec[0] in '/,#\t ':
1872+
sep = spec[0]
1873+
spec = spec[1:]
1874+
elif '/' in spec:
1875+
sep = '/'
1876+
elif ',' in spec:
1877+
sep = ','
1878+
if user_out_spec[0] != '+' and spec == '':
1879+
user_out_spec = sep
1880+
else:
1881+
user_out_spec = re.sub(r'#', sep, default_out_spec) + sep + spec
18291882
else:
18301883
user_out_spec = default_out_spec
18311884

@@ -1998,7 +2051,8 @@ oci_command_list = ['oci'] + c['action'].split(' ') + options_out
19982051
try:
19992052
# oci ... --file - needs read(), not readline()
20002053
if '--file' in options_out and '-' in options_out:
2001-
cli = subprocess.run(oci_command_list, capture_output=True)
2054+
cli = subprocess.run(oci_command_list, stdout=subprocess.PIPE,
2055+
stderr=subprocess.PIPE)
20022056
if cli.stdout != b'':
20032057
sys.stdout.buffer.write(cli.stdout)
20042058
if cli.stderr is not None and cli.stderr:

0 commit comments

Comments
 (0)