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.args = (
 | 
			
		||||
            Args.get_env_arg(required=True),
 | 
			
		||||
            Args.get_create_arg("Create VIP"),
 | 
			
		||||
            Args.get_upload_file_arg("Upload changed VIP configuration "
 | 
			
		||||
                                     "from given file"),
 | 
			
		||||
            Args.get_download_arg("Download VIP configuration"),
 | 
			
		||||
            Args.get_file_arg("Target file with vip data."),
 | 
			
		||||
            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_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 = (
 | 
			
		||||
            ("create", self.create),
 | 
			
		||||
            ("upload", self.upload),
 | 
			
		||||
            ("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):
 | 
			
		||||
        """To upload VIP configuration from some
 | 
			
		||||
            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):
 | 
			
		||||
    return get_int_arg(
 | 
			
		||||
        "ip-address-id",
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,17 @@ class VipMixIn(object):
 | 
			
		||||
            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):
 | 
			
		||||
    """Download VIPs configuration."""
 | 
			
		||||
@@ -45,17 +56,6 @@ class VipDownload(VipMixIn, base.BaseCommand):
 | 
			
		||||
            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
 | 
			
		||||
    def add_network_role_arg(parser):
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
@@ -124,3 +124,59 @@ class VipUpload(VipMixIn, base.BaseCommand):
 | 
			
		||||
    def take_action(self, args):
 | 
			
		||||
        self.client.upload(env_id=args.env, file_path=args.file)
 | 
			
		||||
        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
 | 
			
		||||
        """
 | 
			
		||||
        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]
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    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):
 | 
			
		||||
        url = '/api/v1/clusters/1/network_configuration/ips/vips/'
 | 
			
		||||
        mopen().__enter__().read.return_value = MANY_VIPS_YAML
 | 
			
		||||
@@ -173,8 +177,7 @@ class TestVIPActions(base.UnitTestCase):
 | 
			
		||||
            env_os.path.exists.return_value = True
 | 
			
		||||
            self.execute(['fuel', 'vip', '--env', '1', '--upload', file_path])
 | 
			
		||||
        self.assertEqual(env_os.path.exists.call_count, 1)
 | 
			
		||||
        self.assertEqual(request_put.call_count, 1)
 | 
			
		||||
        self.assertIn(url, request_put.last_request.url)
 | 
			
		||||
        self.check_request(request_put, url)
 | 
			
		||||
        # FileFormatBasedSerializer.read_from_file must not modify given
 | 
			
		||||
        # file path string
 | 
			
		||||
        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()
 | 
			
		||||
                )
 | 
			
		||||
            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(
 | 
			
		||||
            **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):
 | 
			
		||||
        self._test_cmd('download', '--env 1', dict(
 | 
			
		||||
            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])
 | 
			
		||||
        expected_yaml = yaml.safe_load(MANY_VIPS_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)
 | 
			
		||||
 | 
			
		||||
    @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):
 | 
			
		||||
    return VipClient(connection)
 | 
			
		||||
 
 | 
			
		||||
@@ -74,8 +74,9 @@ fuelclient =
 | 
			
		||||
    openstack-config_upload=fuelclient.commands.openstack_config:OpenstackConfigUpload
 | 
			
		||||
    openstack-config_download=fuelclient.commands.openstack_config:OpenstackConfigDownload
 | 
			
		||||
    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_upload=fuelclient.commands.vip:VipUpload
 | 
			
		||||
 | 
			
		||||
[global]
 | 
			
		||||
setup-hooks =
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user