Add create operation for VIP related commands
Change-Id: I888f0da69cccc7cca1befa164ecd8fd75a3158f8 Closes-Bug: #1576255
This commit is contained in:
@@ -32,19 +32,43 @@ class VIPAction(Action):
|
|||||||
self.file_serializer = serializers.FileFormatBasedSerializer()
|
self.file_serializer = serializers.FileFormatBasedSerializer()
|
||||||
self.args = (
|
self.args = (
|
||||||
Args.get_env_arg(required=True),
|
Args.get_env_arg(required=True),
|
||||||
|
Args.get_create_arg("Create VIP"),
|
||||||
Args.get_upload_file_arg("Upload changed VIP configuration "
|
Args.get_upload_file_arg("Upload changed VIP configuration "
|
||||||
"from given file"),
|
"from given file"),
|
||||||
Args.get_download_arg("Download VIP configuration"),
|
Args.get_download_arg("Download VIP configuration"),
|
||||||
Args.get_file_arg("Target file with vip data."),
|
Args.get_file_arg("Target file with vip data."),
|
||||||
Args.get_ip_id_arg("IP address entity identifier"),
|
Args.get_ip_id_arg("IP address entity identifier"),
|
||||||
|
Args.get_ip_address_arg("IP address string"),
|
||||||
Args.get_network_id_arg("Network identifier"),
|
Args.get_network_id_arg("Network identifier"),
|
||||||
Args.get_network_role_arg("Network role string"),
|
Args.get_network_role_arg("Network role string"),
|
||||||
|
Args.get_vip_name_arg("VIP name string"),
|
||||||
|
Args.get_vip_namespace_arg("VIP namespace string"),
|
||||||
)
|
)
|
||||||
self.flag_func_map = (
|
self.flag_func_map = (
|
||||||
|
("create", self.create),
|
||||||
("upload", self.upload),
|
("upload", self.upload),
|
||||||
("download", self.download)
|
("download", self.download)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def create(self, params):
|
||||||
|
"""To create VIP for environment:
|
||||||
|
fuel --env 1 vip create --address 172.16.0.10 --network 1 \\
|
||||||
|
--name public_vip --namespace haproxy
|
||||||
|
"""
|
||||||
|
env = Environment(params.env)
|
||||||
|
vip_kwargs = {
|
||||||
|
"ip_addr": getattr(params, 'ip-address'),
|
||||||
|
"network": getattr(params, 'network'),
|
||||||
|
"vip_name": getattr(params, 'vip-name'),
|
||||||
|
}
|
||||||
|
|
||||||
|
vip_namespace = getattr(params, 'vip-namespace', None)
|
||||||
|
if vip_namespace is not None:
|
||||||
|
vip_kwargs['vip_namespace'] = vip_namespace
|
||||||
|
|
||||||
|
env.create_vip(**vip_kwargs)
|
||||||
|
print("VIP has been created")
|
||||||
|
|
||||||
def upload(self, params):
|
def upload(self, params):
|
||||||
"""To upload VIP configuration from some
|
"""To upload VIP configuration from some
|
||||||
file for some environment:
|
file for some environment:
|
||||||
|
|||||||
@@ -646,6 +646,31 @@ def get_vip_arg(help_msg):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_vip_name_arg(help_msg):
|
||||||
|
return get_str_arg(
|
||||||
|
"vip-name",
|
||||||
|
flags=("--name",),
|
||||||
|
help=help_msg
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_vip_namespace_arg(help_msg, required=False):
|
||||||
|
return get_str_arg(
|
||||||
|
"vip-namespace",
|
||||||
|
flags=("--namespace",),
|
||||||
|
required=required,
|
||||||
|
help=help_msg
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_ip_address_arg(help_msg):
|
||||||
|
return get_str_arg(
|
||||||
|
"ip-address",
|
||||||
|
flags=("--address", "--ip-addr"),
|
||||||
|
help=help_msg
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_ip_id_arg(help_msg):
|
def get_ip_id_arg(help_msg):
|
||||||
return get_int_arg(
|
return get_int_arg(
|
||||||
"ip-address-id",
|
"ip-address-id",
|
||||||
|
|||||||
@@ -30,6 +30,17 @@ class VipMixIn(object):
|
|||||||
help='Environment identifier'
|
help='Environment identifier'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def add_network_id_arg(parser):
|
||||||
|
parser.add_argument(
|
||||||
|
"-n",
|
||||||
|
"--network",
|
||||||
|
type=int,
|
||||||
|
default=None,
|
||||||
|
required=False,
|
||||||
|
help="Network identifier"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class VipDownload(VipMixIn, base.BaseCommand):
|
class VipDownload(VipMixIn, base.BaseCommand):
|
||||||
"""Download VIPs configuration."""
|
"""Download VIPs configuration."""
|
||||||
@@ -45,17 +56,6 @@ class VipDownload(VipMixIn, base.BaseCommand):
|
|||||||
help="IP address entity identifier"
|
help="IP address entity identifier"
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def add_network_id_arg(parser):
|
|
||||||
parser.add_argument(
|
|
||||||
"-n",
|
|
||||||
"--network",
|
|
||||||
type=int,
|
|
||||||
default=None,
|
|
||||||
required=False,
|
|
||||||
help="Network identifier"
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add_network_role_arg(parser):
|
def add_network_role_arg(parser):
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
@@ -124,3 +124,59 @@ class VipUpload(VipMixIn, base.BaseCommand):
|
|||||||
def take_action(self, args):
|
def take_action(self, args):
|
||||||
self.client.upload(env_id=args.env, file_path=args.file)
|
self.client.upload(env_id=args.env, file_path=args.file)
|
||||||
self.app.stdout.write("VIP configuration uploaded.")
|
self.app.stdout.write("VIP configuration uploaded.")
|
||||||
|
|
||||||
|
|
||||||
|
class VipCreate(VipMixIn, base.BaseCommand):
|
||||||
|
"""Create VIP"""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def add_vip_name_arg(parser):
|
||||||
|
parser.add_argument(
|
||||||
|
'-N',
|
||||||
|
'--name',
|
||||||
|
required=True,
|
||||||
|
type=str,
|
||||||
|
help="VIP name"
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def add_ip_addr_arg(parser):
|
||||||
|
parser.add_argument(
|
||||||
|
'-a',
|
||||||
|
'--address',
|
||||||
|
required=True,
|
||||||
|
type=str,
|
||||||
|
help="IP-address for the VIP"
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def add_vip_namespace_arg(parser):
|
||||||
|
parser.add_argument(
|
||||||
|
'--namespace',
|
||||||
|
required=False,
|
||||||
|
type=str,
|
||||||
|
help="VIP namespace"
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(VipCreate, self).get_parser(prog_name)
|
||||||
|
self.add_env_id_arg(parser)
|
||||||
|
self.add_network_id_arg(parser)
|
||||||
|
self.add_vip_name_arg(parser)
|
||||||
|
self.add_ip_addr_arg(parser)
|
||||||
|
self.add_vip_namespace_arg(parser)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def take_action(self, args):
|
||||||
|
vip_kwargs = {
|
||||||
|
"env_id": args.env,
|
||||||
|
"ip_addr": args.address,
|
||||||
|
"network": args.network,
|
||||||
|
"vip_name": args.name,
|
||||||
|
}
|
||||||
|
if args.namespace is not None:
|
||||||
|
vip_kwargs['vip_namespace'] = args.namespace
|
||||||
|
|
||||||
|
self.client.create(**vip_kwargs)
|
||||||
|
|
||||||
|
self.app.stdout.write("VIP has been created.")
|
||||||
|
|||||||
@@ -640,3 +640,11 @@ class Environment(BaseObject):
|
|||||||
:rtype: object
|
:rtype: object
|
||||||
"""
|
"""
|
||||||
return self.connection.put_request(self._get_ip_addrs_url(), data)
|
return self.connection.put_request(self._get_ip_addrs_url(), data)
|
||||||
|
|
||||||
|
def create_vip(self, **vip_kwargs):
|
||||||
|
"""Create VIP through request to Nailgun API
|
||||||
|
|
||||||
|
:param vip_data: attributes of the VIP to be created
|
||||||
|
"""
|
||||||
|
return self.connection.post_request(self._get_ip_addrs_url(),
|
||||||
|
vip_kwargs)
|
||||||
|
|||||||
@@ -161,6 +161,10 @@ class TestVIPActions(base.UnitTestCase):
|
|||||||
mopen.call_args_list[0][0][0]
|
mopen.call_args_list[0][0][0]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def check_request(self, request_mock, url):
|
||||||
|
self.assertEqual(request_mock.call_count, 1)
|
||||||
|
self.assertIn(url, request_mock.last_request.url)
|
||||||
|
|
||||||
def test_vips_upload(self, mos, mopen):
|
def test_vips_upload(self, mos, mopen):
|
||||||
url = '/api/v1/clusters/1/network_configuration/ips/vips/'
|
url = '/api/v1/clusters/1/network_configuration/ips/vips/'
|
||||||
mopen().__enter__().read.return_value = MANY_VIPS_YAML
|
mopen().__enter__().read.return_value = MANY_VIPS_YAML
|
||||||
@@ -173,8 +177,7 @@ class TestVIPActions(base.UnitTestCase):
|
|||||||
env_os.path.exists.return_value = True
|
env_os.path.exists.return_value = True
|
||||||
self.execute(['fuel', 'vip', '--env', '1', '--upload', file_path])
|
self.execute(['fuel', 'vip', '--env', '1', '--upload', file_path])
|
||||||
self.assertEqual(env_os.path.exists.call_count, 1)
|
self.assertEqual(env_os.path.exists.call_count, 1)
|
||||||
self.assertEqual(request_put.call_count, 1)
|
self.check_request(request_put, url)
|
||||||
self.assertIn(url, request_put.last_request.url)
|
|
||||||
# FileFormatBasedSerializer.read_from_file must not modify given
|
# FileFormatBasedSerializer.read_from_file must not modify given
|
||||||
# file path string
|
# file path string
|
||||||
self.assertEqual(file_path, mopen.call_args[0][0])
|
self.assertEqual(file_path, mopen.call_args[0][0])
|
||||||
@@ -189,3 +192,24 @@ class TestVIPActions(base.UnitTestCase):
|
|||||||
'fuel vip --env 1 --upload vips_1.yaml'.split()
|
'fuel vip --env 1 --upload vips_1.yaml'.split()
|
||||||
)
|
)
|
||||||
self.assertIn("doesn't exist", mstderr.getvalue())
|
self.assertIn("doesn't exist", mstderr.getvalue())
|
||||||
|
|
||||||
|
def test_create_vip(self, *_):
|
||||||
|
url = '/api/v1/clusters/1/network_configuration/ips/vips/'
|
||||||
|
request_post = self.m_request.post(url, json={})
|
||||||
|
|
||||||
|
env_id = 1
|
||||||
|
vip_data = {
|
||||||
|
"ip_addr": "127.0.0.1",
|
||||||
|
"network": -1,
|
||||||
|
"vip_name": 'test',
|
||||||
|
"vip_namespace": 'test-namespace'
|
||||||
|
}
|
||||||
|
|
||||||
|
self.execute(["fuel", "--env", str(env_id), "vip", "create",
|
||||||
|
"--ip-addr", vip_data['ip_addr'],
|
||||||
|
"--network", str(vip_data['network']),
|
||||||
|
"--name", vip_data['vip_name'],
|
||||||
|
"--namespace", vip_data['vip_namespace']])
|
||||||
|
|
||||||
|
self.check_request(request_post, url)
|
||||||
|
self.assertEqual(request_post.last_request.json(), vip_data)
|
||||||
|
|||||||
@@ -30,6 +30,22 @@ class TestVIPActions(test_engine.BaseCLITest):
|
|||||||
self.m_client.__getattr__(method).assert_called_once_with(
|
self.m_client.__getattr__(method).assert_called_once_with(
|
||||||
**expected_kwargs)
|
**expected_kwargs)
|
||||||
|
|
||||||
|
def test_vip_create(self):
|
||||||
|
expected = {
|
||||||
|
"env_id": 1,
|
||||||
|
"ip_addr": '127.0.0.1',
|
||||||
|
"network": 1,
|
||||||
|
"vip_name": 'test',
|
||||||
|
"vip_namespace": 'test-namespace'
|
||||||
|
}
|
||||||
|
cmd_line = (
|
||||||
|
'--env {0} --network {1} --address {2} --name {3} --namespace {4}'
|
||||||
|
.format(expected['env_id'], expected['network'],
|
||||||
|
expected['ip_addr'], expected['vip_name'],
|
||||||
|
expected['vip_namespace'])
|
||||||
|
)
|
||||||
|
self._test_cmd('create', cmd_line, expected)
|
||||||
|
|
||||||
def test_vip_download(self):
|
def test_vip_download(self):
|
||||||
self._test_cmd('download', '--env 1', dict(
|
self._test_cmd('download', '--env 1', dict(
|
||||||
env_id=1,
|
env_id=1,
|
||||||
|
|||||||
@@ -64,3 +64,15 @@ class TestVipFacade(test_api.BaseLibTest):
|
|||||||
written_yaml = yaml.safe_load(m_open().write.mock_calls[0][1][0])
|
written_yaml = yaml.safe_load(m_open().write.mock_calls[0][1][0])
|
||||||
expected_yaml = yaml.safe_load(MANY_VIPS_YAML)
|
expected_yaml = yaml.safe_load(MANY_VIPS_YAML)
|
||||||
self.assertEqual(written_yaml, expected_yaml)
|
self.assertEqual(written_yaml, expected_yaml)
|
||||||
|
|
||||||
|
def test_vip_create(self):
|
||||||
|
expected = {'ip_addr': '127.0.0.1', 'vip_name': 'test', 'network': 1}
|
||||||
|
request_post = self.m_request.post(self.res_uri, json={})
|
||||||
|
self.client.create(
|
||||||
|
self.env_id,
|
||||||
|
ip_addr=expected['ip_addr'],
|
||||||
|
vip_name=expected['vip_name'],
|
||||||
|
network=expected['network']
|
||||||
|
)
|
||||||
|
self.assertTrue(request_post.called)
|
||||||
|
self.assertEqual(request_post.last_request.json(), expected)
|
||||||
|
|||||||
@@ -49,6 +49,16 @@ class VipClient(base_v1.BaseV1Client):
|
|||||||
)
|
)
|
||||||
env.set_vips_data(vips_data)
|
env.set_vips_data(vips_data)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create(env_id, ip_addr, network, vip_name):
|
||||||
|
env = objects.Environment(env_id)
|
||||||
|
vip_data = {
|
||||||
|
'ip_addr': ip_addr,
|
||||||
|
'network': network,
|
||||||
|
'vip_name': vip_name
|
||||||
|
}
|
||||||
|
env.create_vip(**vip_data)
|
||||||
|
|
||||||
|
|
||||||
def get_client(connection):
|
def get_client(connection):
|
||||||
return VipClient(connection)
|
return VipClient(connection)
|
||||||
|
|||||||
@@ -74,8 +74,9 @@ fuelclient =
|
|||||||
openstack-config_upload=fuelclient.commands.openstack_config:OpenstackConfigUpload
|
openstack-config_upload=fuelclient.commands.openstack_config:OpenstackConfigUpload
|
||||||
openstack-config_download=fuelclient.commands.openstack_config:OpenstackConfigDownload
|
openstack-config_download=fuelclient.commands.openstack_config:OpenstackConfigDownload
|
||||||
openstack-config_execute=fuelclient.commands.openstack_config:OpenstackConfigExecute
|
openstack-config_execute=fuelclient.commands.openstack_config:OpenstackConfigExecute
|
||||||
vip_upload=fuelclient.commands.vip:VipUpload
|
vip_create=fuelclient.commands.vip:VipCreate
|
||||||
vip_download=fuelclient.commands.vip:VipDownload
|
vip_download=fuelclient.commands.vip:VipDownload
|
||||||
|
vip_upload=fuelclient.commands.vip:VipUpload
|
||||||
|
|
||||||
[global]
|
[global]
|
||||||
setup-hooks =
|
setup-hooks =
|
||||||
|
|||||||
Reference in New Issue
Block a user