174 lines
5.0 KiB
Python
174 lines
5.0 KiB
Python
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import base64
|
|
import binascii
|
|
import json
|
|
import os
|
|
import re
|
|
|
|
from oslo_utils import netutils
|
|
import six
|
|
from six.moves.urllib import parse
|
|
from six.moves.urllib import request
|
|
from gyanclient.common.apiclient import exceptions as apiexec
|
|
from gyanclient.common import cliutils as utils
|
|
from gyanclient import exceptions as exc
|
|
from gyanclient.i18n import _
|
|
|
|
VALID_UNITS = (
|
|
K,
|
|
M,
|
|
G,
|
|
) = (
|
|
1024,
|
|
1024 * 1024,
|
|
1024 * 1024 * 1024,
|
|
)
|
|
|
|
|
|
def common_filters(marker=None, limit=None, sort_key=None,
|
|
sort_dir=None, all_projects=False):
|
|
"""Generate common filters for any list request.
|
|
|
|
:param all_projects: list containers in all projects or not
|
|
:param marker: entity ID from which to start returning entities.
|
|
:param limit: maximum number of entities to return.
|
|
:param sort_key: field to use for sorting.
|
|
:param sort_dir: direction of sorting: 'asc' or 'desc'.
|
|
:returns: list of string filters.
|
|
"""
|
|
filters = []
|
|
if all_projects is True:
|
|
filters.append('all_projects=1')
|
|
if isinstance(limit, int):
|
|
filters.append('limit=%s' % limit)
|
|
if marker is not None:
|
|
filters.append('marker=%s' % marker)
|
|
if sort_key is not None:
|
|
filters.append('sort_key=%s' % sort_key)
|
|
if sort_dir is not None:
|
|
filters.append('sort_dir=%s' % sort_dir)
|
|
return filters
|
|
|
|
|
|
def split_and_deserialize(string):
|
|
"""Split and try to JSON deserialize a string.
|
|
|
|
Gets a string with the KEY=VALUE format, split it (using '=' as the
|
|
separator) and try to JSON deserialize the VALUE.
|
|
:returns: A tuple of (key, value).
|
|
"""
|
|
try:
|
|
key, value = string.split("=", 1)
|
|
except ValueError:
|
|
raise exc.CommandError(_('Attributes must be a list of '
|
|
'PATH=VALUE not "%s"') % string)
|
|
try:
|
|
value = json.loads(value)
|
|
except ValueError:
|
|
pass
|
|
|
|
return (key, value)
|
|
|
|
|
|
def args_array_to_patch(attributes):
|
|
patch = []
|
|
for attr in attributes:
|
|
path, value = split_and_deserialize(attr)
|
|
patch.append({path: value})
|
|
return patch
|
|
|
|
|
|
def format_args(args, parse_comma=True):
|
|
'''Reformat a list of key-value arguments into a dict.
|
|
|
|
Convert arguments into format expected by the API.
|
|
'''
|
|
if not args:
|
|
return {}
|
|
|
|
if parse_comma:
|
|
# expect multiple invocations of --label (or other arguments) but fall
|
|
# back to either , or ; delimited if only one --label is specified
|
|
if len(args) == 1:
|
|
args = args[0].replace(';', ',').split(',')
|
|
|
|
fmt_args = {}
|
|
for arg in args:
|
|
try:
|
|
(k, v) = arg.split(('='), 1)
|
|
except ValueError:
|
|
raise exc.CommandError(_('arguments must be a list of KEY=VALUE '
|
|
'not %s') % arg)
|
|
if k not in fmt_args:
|
|
fmt_args[k] = v
|
|
else:
|
|
if not isinstance(fmt_args[k], list):
|
|
fmt_args[k] = [fmt_args[k]]
|
|
fmt_args[k].append(v)
|
|
|
|
return fmt_args
|
|
|
|
|
|
def print_list_field(field):
|
|
return lambda obj: ', '.join(getattr(obj, field))
|
|
|
|
|
|
def remove_null_parms(**kwargs):
|
|
new = {}
|
|
for (key, value) in kwargs.items():
|
|
if value is not None:
|
|
new[key] = value
|
|
return new
|
|
|
|
|
|
def list_nodes(nodes):
|
|
columns = ('uuid', 'name', 'type', 'status')
|
|
utils.print_list(nodes, columns,
|
|
{'versions': print_list_field('versions')},
|
|
sortby_index=None)
|
|
|
|
|
|
def list_models(models):
|
|
columns = ('uuid', 'name', 'type', 'status', 'state', 'deployed_url',
|
|
'deployed_on')
|
|
utils.print_list(models, columns,
|
|
{'versions': print_list_field('versions')},
|
|
sortby_index=None)
|
|
|
|
def normalise_file_path_to_url(path):
|
|
if parse.urlparse(path).scheme:
|
|
return path
|
|
path = os.path.abspath(path)
|
|
return parse.urljoin('file:', request.pathname2url(path))
|
|
|
|
|
|
def base_url_for_url(url):
|
|
parsed = parse.urlparse(url)
|
|
parsed_dir = os.path.dirname(parsed.path)
|
|
return parse.urljoin(url, parsed_dir)
|
|
|
|
|
|
def encode_file_data(data):
|
|
if six.PY3 and isinstance(data, str):
|
|
data = data.encode('utf-8')
|
|
return base64.b64encode(data).decode('utf-8')
|
|
|
|
|
|
def decode_file_data(data):
|
|
# Py3 raises binascii.Error instead of TypeError as in Py27
|
|
try:
|
|
return base64.b64decode(data)
|
|
except (TypeError, binascii.Error):
|
|
raise exc.CommandError(_('Invalid Base 64 file data.'))
|