From d22f26446ad49b6eec099d57298bf9af42ea161d Mon Sep 17 00:00:00 2001
From: Stephen Finucane <stephenfin@redhat.com>
Date: Tue, 9 Jul 2024 14:23:31 +0100
Subject: [PATCH] compute: Prevent use of conflicting v*-fixed-ip for 'server
 create --nic'

Currently this check is handled by novaclient. In the future, we won't
have that so we need to do it ourselves. Do so now, fixing a typo along
the way and adding tests to prevent regressions.

Change-Id: Iaa9c087d846390b6a4f95ed3fa121dd8dc640903
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
---
 openstackclient/compute/v2/server.py          | 13 +++++--
 .../tests/unit/compute/v2/test_server.py      | 39 +++++++++++++++++++
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index ed5fe0fa96..ceac614d61 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -931,10 +931,17 @@ class NICAction(argparse.Action):
 
         if info['net-id'] and info['port-id']:
             msg = _(
-                'Invalid argument %s; either network or port should be '
-                'specified but not both'
+                "Invalid argument %s; either 'network' or 'port' should be "
+                "specified but not both"
             )
-            raise argparse.ArgumenteError(self, msg % values)
+            raise argparse.ArgumentError(self, msg % values)
+
+        if info['v4-fixed-ip'] and info['v6-fixed-ip']:
+            msg = _(
+                "Invalid argument %s; either 'v4-fixed-ip' or 'v6-fixed-ip' "
+                "should be specified but not both"
+            )
+            raise argparse.ArgumentError(self, msg % values)
 
         getattr(namespace, self.dest).append(info)
 
diff --git a/openstackclient/tests/unit/compute/v2/test_server.py b/openstackclient/tests/unit/compute/v2/test_server.py
index 8dddc32558..858e4eca66 100644
--- a/openstackclient/tests/unit/compute/v2/test_server.py
+++ b/openstackclient/tests/unit/compute/v2/test_server.py
@@ -2308,7 +2308,46 @@ class TestServerCreate(TestServer):
             arglist,
             [],
         )
+        self.assertNotCalled(self.servers_mock.create)
 
+    def test_server_create_with_conflicting_net_port_filters(self):
+        arglist = [
+            '--image',
+            'image1',
+            '--flavor',
+            'flavor1',
+            '--nic',
+            'net-id=abc,port-id=xyz',
+            self.new_server.name,
+        ]
+        exc = self.assertRaises(
+            test_utils.ParserException,
+            self.check_parser,
+            self.cmd,
+            arglist,
+            [],
+        )
+        self.assertIn("either 'network' or 'port'", str(exc))
+        self.assertNotCalled(self.servers_mock.create)
+
+    def test_server_create_with_conflicting_fixed_ip_filters(self):
+        arglist = [
+            '--image',
+            'image1',
+            '--flavor',
+            'flavor1',
+            '--nic',
+            'net-id=abc,v4-fixed-ip=1.2.3.4,v6-fixed-ip=2001:db8:abcd',
+            self.new_server.name,
+        ]
+        exc = self.assertRaises(
+            test_utils.ParserException,
+            self.check_parser,
+            self.cmd,
+            arglist,
+            [],
+        )
+        self.assertIn("either 'v4-fixed-ip' or 'v6-fixed-ip'", str(exc))
         self.assertNotCalled(self.servers_mock.create)
 
     @mock.patch.object(common_utils, 'wait_for_status', return_value=True)