Skip to content

Commit be7652c

Browse files
S0okJuhalucinor
authored andcommitted
Add domain-related tool (#49)
* feat(identity): Add get-domain, get-domains(#31) - Change response/keystone.py -> response/identity - Add get-domain, get-domains tool * feat(identity): Register tool(#31) * feat(identity): Add create domain tool(#31) - Add create_domain tool - Tests are updated and passing * feat(identity): Add create, delete, update domain(#31) - Add create, delete, update domain tool - Test codes are updated and passing * feat(identity): Add id field in update domain tool(#31) - Add id field in update_domain tool - Tests are updated and passing * feat(identity): Add id field in update domain tool(#31) * fix(identity): Fix linter problem(#31)
1 parent 6e12c4f commit be7652c

File tree

3 files changed

+372
-31
lines changed

3 files changed

+372
-31
lines changed

src/openstack_mcp_server/tools/identity_tools.py

Lines changed: 89 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ def register_tools(self, mcp: FastMCP):
2222

2323
mcp.tool()(self.get_domains)
2424
mcp.tool()(self.get_domain)
25+
mcp.tool()(self.create_domain)
26+
mcp.tool()(self.delete_domain)
27+
mcp.tool()(self.update_domain)
2528

2629
def get_regions(self) -> list[Region]:
2730
"""
@@ -43,7 +46,7 @@ def get_region(self, id: str) -> Region:
4346
"""
4447
Get a region.
4548
46-
:param id: The ID of the region. (required)
49+
:param id: The ID of the region.
4750
4851
:return: The Region object.
4952
"""
@@ -53,12 +56,12 @@ def get_region(self, id: str) -> Region:
5356

5457
return Region(id=region.id, description=region.description)
5558

56-
def create_region(self, id: str, description: str = "") -> Region:
59+
def create_region(self, id: str, description: str | None = None) -> Region:
5760
"""
5861
Create a new region.
5962
60-
:param id: The ID of the region. (required)
61-
:param description: The description of the region. (optional)
63+
:param id: The ID of the region.
64+
:param description: The description of the region.
6265
6366
:return: The created Region object.
6467
"""
@@ -72,7 +75,7 @@ def delete_region(self, id: str) -> None:
7275
"""
7376
Delete a region.
7477
75-
:param id: The ID of the region. (required)
78+
:param id: The ID of the region.
7679
7780
:return: None
7881
"""
@@ -83,12 +86,12 @@ def delete_region(self, id: str) -> None:
8386

8487
return None
8588

86-
def update_region(self, id: str, description: str = "") -> Region:
89+
def update_region(self, id: str, description: str | None = None) -> Region:
8790
"""
8891
Update a region.
8992
90-
:param id: The ID of the region. (required)
91-
:param description: The string description of the region. (optional)
93+
:param id: The ID of the region.
94+
:param description: The string description of the region.
9295
9396
:return: The updated Region object.
9497
"""
@@ -124,21 +127,96 @@ def get_domains(self) -> list[Domain]:
124127
)
125128
return domain_list
126129

127-
def get_domain(self, id: str) -> Domain:
130+
def get_domain(self, name: str) -> Domain:
128131
"""
129132
Get a domain.
130133
131-
:param id: The ID of the domain. (required)
134+
:param name: The name of the domain.
132135
133136
:return: The Domain object.
134137
"""
135138
conn = get_openstack_conn()
136139

137-
domain = conn.identity.get_domain(domain=id)
140+
domain = conn.identity.find_domain(name_or_id=name)
138141

139142
return Domain(
140143
id=domain.id,
141144
name=domain.name,
142145
description=domain.description,
143146
is_enabled=domain.is_enabled,
144147
)
148+
149+
def create_domain(
150+
self,
151+
name: str,
152+
description: str | None = None,
153+
is_enabled: bool | None = False,
154+
) -> Domain:
155+
"""
156+
Create a new domain.
157+
158+
:param name: The name of the domain.
159+
:param description: The description of the domain.
160+
:param is_enabled: Whether the domain is enabled.
161+
"""
162+
conn = get_openstack_conn()
163+
164+
domain = conn.identity.create_domain(
165+
name=name,
166+
description=description,
167+
enabled=is_enabled,
168+
)
169+
170+
return Domain(
171+
id=domain.id,
172+
name=domain.name,
173+
description=domain.description,
174+
is_enabled=domain.is_enabled,
175+
)
176+
177+
def delete_domain(self, name: str) -> None:
178+
"""
179+
Delete a domain.
180+
181+
:param name: The name of the domain.
182+
"""
183+
conn = get_openstack_conn()
184+
185+
domain = conn.identity.find_domain(name_or_id=name)
186+
conn.identity.delete_domain(domain=domain, ignore_missing=False)
187+
188+
return None
189+
190+
def update_domain(
191+
self,
192+
id: str,
193+
name: str | None = None,
194+
description: str | None = None,
195+
is_enabled: bool | None = None,
196+
) -> Domain:
197+
"""
198+
Update a domain.
199+
200+
:param id: The ID of the domain.
201+
:param name: The name of the domain.
202+
:param description: The description of the domain.
203+
:param is_enabled: Whether the domain is enabled.
204+
"""
205+
conn = get_openstack_conn()
206+
207+
args = {}
208+
if name is not None:
209+
args["name"] = name
210+
if description is not None:
211+
args["description"] = description
212+
if is_enabled is not None:
213+
args["is_enabled"] = is_enabled
214+
215+
updated_domain = conn.identity.update_domain(domain=id, **args)
216+
217+
return Domain(
218+
id=updated_domain.id,
219+
name=updated_domain.name,
220+
description=updated_domain.description,
221+
is_enabled=updated_domain.is_enabled,
222+
)

src/openstack_mcp_server/tools/response/identity.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
# In this case, we are only using description field as optional.
66
class Region(BaseModel):
77
id: str
8-
description: str = ""
8+
description: str | None = None
99

1010

1111
class Domain(BaseModel):
1212
id: str
1313
name: str
14-
description: str = ""
15-
is_enabled: bool = False
14+
description: str | None = None
15+
is_enabled: bool | None = None

0 commit comments

Comments
 (0)