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
This commit is contained in:
@@ -16,6 +16,9 @@
|
||||
|
||||
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 _
|
||||
@@ -175,3 +178,41 @@ def parse_command(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
|
||||
|
@@ -125,6 +125,19 @@ class CreateContainer(command.ShowOne):
|
||||
help='The key-value pair(s) for scheduler to select host. '
|
||||
'The format of this parameter is "key=value[,key=value]". '
|
||||
'May be used multiple times.')
|
||||
parser.add_argument(
|
||||
'--nets',
|
||||
metavar='<auto, networks=networks, port=port-uuid,'
|
||||
'v4-fixed-ip=ip-addr,v6-fixed-ip=ip-addr>',
|
||||
action='append',
|
||||
default=[],
|
||||
help='Create network enpoints for the container. '
|
||||
'auto: do not specify the network, zun will automatically'
|
||||
'create one. '
|
||||
'network: attach container to the specified neutron networks.'
|
||||
' port: attach container to the neutron port with this UUID. '
|
||||
'v4-fixed-ip: IPv4 fixed address for container. '
|
||||
'v6-fixed-ip: IPv6 fixed address for container.')
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
@@ -149,6 +162,7 @@ class CreateContainer(command.ShowOne):
|
||||
if parsed_args.interactive:
|
||||
opts['interactive'] = True
|
||||
opts['hints'] = zun_utils.format_args(parsed_args.hint)
|
||||
opts['nets'] = zun_utils.parse_nets(parsed_args.nets)
|
||||
|
||||
opts = zun_utils.remove_null_parms(**opts)
|
||||
container = client.containers.create(**opts)
|
||||
@@ -606,6 +620,25 @@ class RunContainer(command.ShowOne):
|
||||
help='The key-value pair(s) for scheduler to select host. '
|
||||
'The format of this parameter is "key=value[,key=value]". '
|
||||
'May be used multiple times.')
|
||||
parser.add_argument(
|
||||
'--nets',
|
||||
metavar='[net]',
|
||||
action='append',
|
||||
default=[],
|
||||
help='Networks that container will connect to.')
|
||||
parser.add_argument(
|
||||
'--nets',
|
||||
metavar='<auto, networks=networks, port=port-uuid,'
|
||||
'v4-fixed-ip=ip-addr,v6-fixed-ip=ip-addr>',
|
||||
action='append',
|
||||
default=[],
|
||||
help='Create network enpoints for the container. '
|
||||
'auto: do not specify the network, zun will automatically'
|
||||
'create one. '
|
||||
'network: attach container to the specified neutron networks.'
|
||||
' port: attach container to the neutron port with this UUID. '
|
||||
'v4-fixed-ip: IPv4 fixed address for container. '
|
||||
'v6-fixed-ip: IPv6 fixed address for container.')
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
@@ -630,6 +663,7 @@ class RunContainer(command.ShowOne):
|
||||
if parsed_args.interactive:
|
||||
opts['interactive'] = True
|
||||
opts['hints'] = zun_utils.format_args(parsed_args.hint)
|
||||
opts['nets'] = zun_utils.parse_nets(parsed_args.nets)
|
||||
|
||||
opts = zun_utils.remove_null_parms(**opts)
|
||||
container = client.containers.run(**opts)
|
||||
|
@@ -208,3 +208,39 @@ class CliUtilsTest(test_utils.BaseTestCase):
|
||||
('c', dict_out['c'])])
|
||||
|
||||
self.assertEqual(six.text_type(dict_exp), six.text_type(dict_act))
|
||||
|
||||
|
||||
class ParseNetsTest(test_utils.BaseTestCase):
|
||||
|
||||
def test_no_nets(self):
|
||||
nets = []
|
||||
result = utils.parse_nets(nets)
|
||||
self.assertEqual([], result)
|
||||
|
||||
def test_nets_with_network(self):
|
||||
nets = [' network = 1234567 , v4-fixed-ip = 172.17.0.3 ']
|
||||
result = utils.parse_nets(nets)
|
||||
self.assertEqual([{'network': '1234567', 'v4-fixed-ip': '172.17.0.3',
|
||||
'port': '', 'v6-fixed-ip': ''}], result)
|
||||
|
||||
def test_nets_with_port(self):
|
||||
nets = ['port=1234567, v6-fixed-ip=2001:db8::2']
|
||||
result = utils.parse_nets(nets)
|
||||
self.assertEqual([{'network': '', 'v4-fixed-ip': '',
|
||||
'port': '1234567', 'v6-fixed-ip': '2001:db8::2'}],
|
||||
result)
|
||||
|
||||
def test_nets_with_only_ip(self):
|
||||
nets = ['v4-fixed-ip = 172.17.0.3']
|
||||
self.assertRaises(exc.CommandError,
|
||||
utils.parse_nets, nets)
|
||||
|
||||
def test_nets_with_both_network_port(self):
|
||||
nets = ['port=1234567, network=2345678, v4-fixed-ip=172.17.0.3']
|
||||
self.assertRaises(exc.CommandError,
|
||||
utils.parse_nets, nets)
|
||||
|
||||
def test_nets_with_invalid_ip(self):
|
||||
nets = ['network=1234567, v4-fixed-ip=23.555.567,789']
|
||||
self.assertRaises(exc.CommandError,
|
||||
utils.parse_nets, nets)
|
||||
|
@@ -22,7 +22,7 @@ from zunclient import exceptions
|
||||
CREATION_ATTRIBUTES = ['name', 'image', 'command', 'cpu', 'memory',
|
||||
'environment', 'workdir', 'labels', 'image_pull_policy',
|
||||
'restart_policy', 'interactive', 'image_driver',
|
||||
'security_groups', 'hints']
|
||||
'security_groups', 'hints', 'nets']
|
||||
|
||||
|
||||
class Container(base.Resource):
|
||||
|
@@ -97,6 +97,18 @@ def _show_container(container):
|
||||
help='The key-value pair(s) for scheduler to select host. '
|
||||
'The format of this parameter is "key=value[,key=value]". '
|
||||
'May be used multiple times.')
|
||||
@utils.arg('--nets',
|
||||
action='append',
|
||||
default=[],
|
||||
metavar='<auto, network=network, port=port-uuid,'
|
||||
'v4-fixed-ip=ip-addr,v6-fixed-ip=ip-addr>',
|
||||
help='Create network enpoints for the container. '
|
||||
'auto: do not specify the network, zun will automatically'
|
||||
'create one. '
|
||||
'network: attach container to the specified neturon networks. '
|
||||
'port: attach container to the neutron port with this UUID. '
|
||||
'v4-fixed-ip: IPv4 fixed address for container. '
|
||||
'v6-fixed-ip: IPv6 fixed address for container.')
|
||||
def do_create(cs, args):
|
||||
"""Create a container."""
|
||||
opts = {}
|
||||
@@ -110,6 +122,8 @@ def do_create(cs, args):
|
||||
opts['image_pull_policy'] = args.image_pull_policy
|
||||
opts['image_driver'] = args.image_driver
|
||||
opts['hints'] = zun_utils.format_args(args.hint)
|
||||
nets = zun_utils.parse_nets(args.nets)
|
||||
opts['nets'] = nets
|
||||
|
||||
if args.security_group:
|
||||
opts['security_groups'] = args.security_group
|
||||
@@ -443,6 +457,18 @@ def do_kill(cs, args):
|
||||
help='The key-value pair(s) for scheduler to select host. '
|
||||
'The format of this parameter is "key=value[,key=value]". '
|
||||
'May be used multiple times.')
|
||||
@utils.arg('--nets',
|
||||
action='append',
|
||||
default=[],
|
||||
metavar='<auto, network=network, port=port-uuid,'
|
||||
'v4-fixed-ip=ip-addr,v6-fixed-ip=ip-addr>',
|
||||
help='Create network enpoints for the container. '
|
||||
'auto: do not specify the network, zun will automatically'
|
||||
'create one. '
|
||||
'network: attach container to the specified neutron networks. '
|
||||
'port: attach container to the neutron port with this UUID. '
|
||||
'v4-fixed-ip: IPv4 fixed address for container. '
|
||||
'v6-fixed-ip: IPv6 fixed address for container.')
|
||||
def do_run(cs, args):
|
||||
"""Run a command in a new container."""
|
||||
opts = {}
|
||||
@@ -456,6 +482,8 @@ def do_run(cs, args):
|
||||
opts['image_pull_policy'] = args.image_pull_policy
|
||||
opts['image_driver'] = args.image_driver
|
||||
opts['hints'] = zun_utils.format_args(args.hint)
|
||||
nets = zun_utils.parse_nets(args.nets)
|
||||
opts['nets'] = nets
|
||||
|
||||
if args.security_group:
|
||||
opts['security_groups'] = args.security_group
|
||||
|
Reference in New Issue
Block a user