From 533af9f1b2de40d98f69e83cdf89ecf254cf3879 Mon Sep 17 00:00:00 2001
From: yanpuqing <yanpq@awcloud.com>
Date: Mon, 20 May 2019 06:47:44 +0000
Subject: [PATCH] Client should parse string to boolean for value 'is_domain'

When we use "--property" parameter, client get lists these the
value is string type, but the type of the value 'is_domain'
should be boolean, so we should judge it and parse it.
The patch parse string to boolean for value 'is_domain'.

Co-Authored-By: Lance Bragstad <lbragstad@gmail.com>

Change-Id: I37c9eb854524bde3a1530bfe2e3a03810fb1a676
Task: 30039
Story: 2005246
---
 openstackclient/identity/v3/project.py        |   8 ++
 .../tests/unit/identity/v3/test_project.py    | 120 ++++++++++++++++++
 .../notes/bug-2005246-3fb70206bafc5444.yaml   |   5 +
 3 files changed, 133 insertions(+)
 create mode 100644 releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml

diff --git a/openstackclient/identity/v3/project.py b/openstackclient/identity/v3/project.py
index e32da165b4..5e8ce82981 100644
--- a/openstackclient/identity/v3/project.py
+++ b/openstackclient/identity/v3/project.py
@@ -106,6 +106,14 @@ class CreateProject(command.ShowOne):
         kwargs = {}
         if parsed_args.property:
             kwargs = parsed_args.property.copy()
+        if 'is_domain' in kwargs.keys():
+            if kwargs['is_domain'].lower() == "true":
+                kwargs['is_domain'] = True
+            elif kwargs['is_domain'].lower() == "false":
+                kwargs['is_domain'] = False
+            elif kwargs['is_domain'].lower() == "none":
+                kwargs['is_domain'] = None
+
         kwargs['tags'] = list(set(parsed_args.tags))
 
         try:
diff --git a/openstackclient/tests/unit/identity/v3/test_project.py b/openstackclient/tests/unit/identity/v3/test_project.py
index 8852aa8ecc..dfd0805b29 100644
--- a/openstackclient/tests/unit/identity/v3/test_project.py
+++ b/openstackclient/tests/unit/identity/v3/test_project.py
@@ -357,6 +357,126 @@ class TestProjectCreate(TestProject):
         self.assertEqual(self.columns, columns)
         self.assertEqual(self.datalist, data)
 
+    def test_project_create_is_domain_false_property(self):
+        arglist = [
+            '--property', 'is_domain=false',
+            self.project.name,
+        ]
+        verifylist = [
+            ('parent', None),
+            ('enable', False),
+            ('disable', False),
+            ('name', self.project.name),
+            ('tags', []),
+            ('property', {'is_domain': 'false'}),
+            ('name', self.project.name),
+        ]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        # In base command class ShowOne in cliff, abstract method take_action()
+        # returns a two-part tuple with a tuple of column names and a tuple of
+        # data to be shown.
+        columns, data = self.cmd.take_action(parsed_args)
+
+        # Set expected values
+        kwargs = {
+            'name': self.project.name,
+            'domain': None,
+            'description': None,
+            'enabled': True,
+            'parent': None,
+            'is_domain': False,
+            'tags': [],
+            'options': {},
+        }
+        self.projects_mock.create.assert_called_with(
+            **kwargs
+        )
+
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.datalist, data)
+
+    def test_project_create_is_domain_true_property(self):
+        arglist = [
+            '--property', 'is_domain=true',
+            self.project.name,
+        ]
+        verifylist = [
+            ('parent', None),
+            ('enable', False),
+            ('disable', False),
+            ('name', self.project.name),
+            ('tags', []),
+            ('property', {'is_domain': 'true'}),
+            ('name', self.project.name),
+        ]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        # In base command class ShowOne in cliff, abstract method take_action()
+        # returns a two-part tuple with a tuple of column names and a tuple of
+        # data to be shown.
+        columns, data = self.cmd.take_action(parsed_args)
+
+        # Set expected values
+        kwargs = {
+            'name': self.project.name,
+            'domain': None,
+            'description': None,
+            'enabled': True,
+            'parent': None,
+            'is_domain': True,
+            'tags': [],
+            'options': {},
+        }
+        self.projects_mock.create.assert_called_with(
+            **kwargs
+        )
+
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.datalist, data)
+
+    def test_project_create_is_domain_none_property(self):
+        arglist = [
+            '--property', 'is_domain=none',
+            self.project.name,
+        ]
+        verifylist = [
+            ('parent', None),
+            ('enable', False),
+            ('disable', False),
+            ('name', self.project.name),
+            ('tags', []),
+            ('property', {'is_domain': 'none'}),
+            ('name', self.project.name),
+        ]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        # In base command class ShowOne in cliff, abstract method take_action()
+        # returns a two-part tuple with a tuple of column names and a tuple of
+        # data to be shown.
+        columns, data = self.cmd.take_action(parsed_args)
+
+        # Set expected values
+        kwargs = {
+            'name': self.project.name,
+            'domain': None,
+            'description': None,
+            'enabled': True,
+            'parent': None,
+            'is_domain': None,
+            'tags': [],
+            'options': {},
+        }
+        self.projects_mock.create.assert_called_with(
+            **kwargs
+        )
+
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.datalist, data)
+
     def test_project_create_parent(self):
         self.parent = identity_fakes.FakeProject.create_one_project()
         self.project = identity_fakes.FakeProject.create_one_project(
diff --git a/releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml b/releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml
new file mode 100644
index 0000000000..4d7bdd5d42
--- /dev/null
+++ b/releasenotes/notes/bug-2005246-3fb70206bafc5444.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+  - |
+    [Story `2005246 <https://storyboard.openstack.org/#!/story/2005246>`_]
+    The `is_domain` property safely handles type checking.