python-zunclient/zunclient/common/utils.py
ShunliZhou c27da4b593 Add network options to zunclient
Add network options to zunclient to allow use specify the pre
created network to use to create container.

CLI format like 'zun create --nets
network=982a86dc1194,v4-fixed-ip=172.17.0.3 --nets
port=1234567,v6-fixed-ip=2001:db8::2 nginx bash'

Value passed to api like this ‘[{u'v4-fixed-ip': u'172.17.0.3',
u'network': u'982a86dc1194', u'v6-fixed-ip': u'', u'port': u''},
{u'v4-fixed-ip': u'', u'network': u'', u'v6-fixed-ip':
u'2001:db8::2', u'port': u'1234567'}]'’.

Change-Id: I6507d153e97564160308dabe90ce8693bc061863
2017-07-05 14:54:36 +08:00

219 lines
6.5 KiB
Python

#
# Copyright 2012 OpenStack LLC.
# All Rights Reserved.
#
# 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 json
from oslo_utils import netutils
from zunclient.common.apiclient import exceptions as apiexec
from zunclient.common import cliutils as utils
from zunclient import exceptions as exc
from zunclient.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_tenants=False):
"""Generate common filters for any list request.
:param all_tenants: list containers in all tenants 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_tenants is True:
filters.append('all_tenants=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 check_restart_policy(policy):
if ":" in policy:
name, count = policy.split(":")
restart_policy = {"Name": name, "MaximumRetryCount": count}
else:
restart_policy = {"Name": policy,
"MaximumRetryCount": '0'}
return restart_policy
def remove_null_parms(**kwargs):
new = {}
for (key, value) in kwargs.items():
if value is not None:
new[key] = value
return new
def check_container_status(container, status):
if getattr(container, 'status', None) == status:
return True
else:
return False
def format_container_addresses(container):
addresses = getattr(container, 'addresses', {})
output = []
try:
for address_name, address_list in addresses.items():
for a in address_list:
output.append(a['addr'])
except Exception:
pass
setattr(container, 'addresses', ', '.join(output))
container._info['addresses'] = ', '.join(output)
def list_containers(containers):
for c in containers:
format_container_addresses(c)
columns = ('uuid', 'name', 'image', 'status', 'task_state', 'addresses',
'ports')
utils.print_list(containers, columns,
{'versions': print_list_field('versions')},
sortby_index=None)
def parse_command(command):
output = []
if command:
for c in command:
c = '"' + c + '"'
output.append(c)
return " ".join(output)
def parse_nets(ns):
err_msg = ("Invalid nets argument '%s'. nets arguments must be of "
"the form --nets <network=network, v4-fixed-ip=ip-addr,"
"v6-fixed-ip=ip-addr, port=port-uuid>, "
"with only one of network, or port specified.")
nets = []
for net_str in ns:
net_info = {"network": "", "v4-fixed-ip": "", "v6-fixed-ip": "",
"port": ""}
for kv_str in net_str.split(","):
try:
k, v = kv_str.split("=", 1)
k = k.strip()
v = v.strip()
except ValueError:
raise apiexec.CommandError(err_msg % net_str)
if k in net_info:
if net_info[k]:
raise apiexec.CommandError(err_msg % net_str)
net_info[k] = v
else:
raise apiexec.CommandError(err_msg % net_str)
if net_info['v4-fixed-ip'] and not netutils.is_valid_ipv4(
net_info['v4-fixed-ip']):
raise apiexec.CommandError("Invalid ipv4 address.")
if net_info['v6-fixed-ip'] and not netutils.is_valid_ipv6(
net_info['v6-fixed-ip']):
raise apiexec.CommandError("Invalid ipv6 address.")
if bool(net_info['network']) == bool(net_info['port']):
raise apiexec.CommandError(err_msg % net_str)
nets.append(net_info)
return nets