Skip to content

Commit d7d60da

Browse files
committed
feat(identity): Add create domain tool(#31)
- Add create_domain tool - Tests are updated and passing
1 parent e396261 commit d7d60da

File tree

2 files changed

+143
-2
lines changed

2 files changed

+143
-2
lines changed

src/openstack_mcp_server/tools/identity_tools.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from fastmcp import FastMCP
22

33
from .base import get_openstack_conn
4-
from .response.identity import Region, Domain
4+
from .response.identity import Domain, Region
55

66

77
class IdentityTools:
@@ -22,6 +22,7 @@ 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)
2526

2627
def get_regions(self) -> list[Region]:
2728
"""
@@ -133,3 +134,25 @@ def get_domain(self, id: str) -> Domain:
133134

134135
return Domain(id=domain.id, name=domain.name, description=domain.description, is_enabled=domain.is_enabled)
135136

137+
def create_domain(self,
138+
id: str,
139+
name: str,
140+
description: str = "",
141+
is_enabled: bool = False,
142+
) -> Domain:
143+
"""
144+
Create a new domain.
145+
146+
:param id: The ID of the domain. (required)
147+
:param name: The name of the domain. (required)
148+
:param description: The description of the domain. (optional)
149+
:param is_enabled: Whether the domain is enabled. (optional)
150+
151+
:return: The created Domain object.
152+
"""
153+
154+
conn = get_openstack_conn()
155+
156+
domain = conn.identity.create_domain(id=id, name=name, description=description, is_enabled=is_enabled)
157+
158+
return Domain(id=domain.id, name=domain.name, description=domain.description, is_enabled=domain.is_enabled)

tests/tools/test_identity_tools.py

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from openstack import exceptions
66

77
from openstack_mcp_server.tools.identity_tools import IdentityTools
8-
from openstack_mcp_server.tools.response.identity import Region, Domain
8+
from openstack_mcp_server.tools.response.identity import Domain, Region
99

1010

1111
class TestIdentityTools:
@@ -428,3 +428,121 @@ def test_get_domain_not_found(self, mock_get_openstack_conn_identity):
428428

429429
# Verify mock calls
430430
mock_conn.identity.get_domain.assert_called_once_with(domain="domainone")
431+
432+
def test_create_domain_success(self, mock_get_openstack_conn_identity):
433+
"""Test creating a identity domain successfully."""
434+
mock_conn = mock_get_openstack_conn_identity
435+
436+
# Create mock domain object
437+
mock_domain = Mock()
438+
mock_domain.id = "domainone"
439+
mock_domain.name = "DomainOne"
440+
mock_domain.description = "Domain One description"
441+
mock_domain.is_enabled = False
442+
443+
# Configure mock domain.create_domain()
444+
mock_conn.identity.create_domain.return_value = mock_domain
445+
446+
# Test create_domain()
447+
identity_tools = self.get_identity_tools()
448+
result = identity_tools.create_domain(id="domainone", name="DomainOne", description="Domain One description", is_enabled=False)
449+
450+
# Verify results
451+
assert result == Domain(id="domainone", name="DomainOne", description="Domain One description", is_enabled=False)
452+
453+
# Verify mock calls
454+
mock_conn.identity.create_domain.assert_called_once_with(id="domainone", name="DomainOne", description="Domain One description", is_enabled=False)
455+
456+
457+
def test_create_domain_with_empty_id(self, mock_get_openstack_conn_identity):
458+
"""Test creating a identity domain with an empty ID."""
459+
mock_conn = mock_get_openstack_conn_identity
460+
461+
# Create mock domain object
462+
mock_domain = Mock()
463+
mock_domain.id = ""
464+
mock_domain.name = "DomainOne"
465+
mock_domain.description = "Domain One description"
466+
mock_domain.is_enabled = False
467+
468+
# Configure mock domain.create_domain()
469+
mock_conn.identity.create_domain.return_value = mock_domain
470+
471+
# If id is empty, the id will be generated by the server
472+
temp_id = "abcdefghijklmnopqrs12345"
473+
mock_domain.id = temp_id
474+
475+
# Test create_domain()
476+
identity_tools = self.get_identity_tools()
477+
result = identity_tools.create_domain(id="", name="DomainOne", description="Domain One description", is_enabled=False)
478+
479+
# Verify results
480+
assert result == Domain(id=temp_id, name="DomainOne", description="Domain One description", is_enabled=False)
481+
482+
def test_create_domain_with_empty_name(self, mock_get_openstack_conn_identity):
483+
"""Test creating a identity domain with an empty name."""
484+
mock_conn = mock_get_openstack_conn_identity
485+
486+
# Create mock domain object
487+
mock_domain = Mock()
488+
mock_domain.id = "domainone"
489+
mock_domain.name = ""
490+
mock_domain.description = "Domain One description"
491+
mock_domain.is_enabled = False
492+
493+
# Configure mock domain.create_domain()
494+
mock_conn.identity.create_domain.return_value = mock_domain
495+
496+
# Test create_domain()
497+
identity_tools = self.get_identity_tools()
498+
result = identity_tools.create_domain(id="domainone", name="", description="Domain One description", is_enabled=False)
499+
500+
# Verify results
501+
assert result == Domain(id="domainone", name="", description="Domain One description", is_enabled=False)
502+
503+
def test_create_domain_with_empty_description(self, mock_get_openstack_conn_identity):
504+
"""Test creating a identity domain with an empty description."""
505+
mock_conn = mock_get_openstack_conn_identity
506+
507+
# Create mock domain object
508+
mock_domain = Mock()
509+
mock_domain.id = "domainone"
510+
mock_domain.name = "DomainOne"
511+
mock_domain.description = ""
512+
mock_domain.is_enabled = False
513+
514+
# Configure mock domain.create_domain()
515+
mock_conn.identity.create_domain.return_value = mock_domain
516+
517+
# Test create_domain()
518+
identity_tools = self.get_identity_tools()
519+
result = identity_tools.create_domain(id="domainone", name="DomainOne", description="", is_enabled=False)
520+
521+
# Verify results
522+
assert result == Domain(id="domainone", name="DomainOne", description="", is_enabled=False)
523+
524+
def test_create_domain_with_empty_is_enabled(self, mock_get_openstack_conn_identity):
525+
"""Test creating a identity domain with an empty is_enabled."""
526+
mock_conn = mock_get_openstack_conn_identity
527+
528+
# Create mock domain object
529+
mock_domain = Mock()
530+
mock_domain.id = "domainone"
531+
mock_domain.name = "DomainOne"
532+
mock_domain.description = "Domain One description"
533+
mock_domain.is_enabled = False
534+
535+
# Configure mock domain.create_domain()
536+
mock_conn.identity.create_domain.return_value = mock_domain
537+
538+
# Test create_domain()
539+
identity_tools = self.get_identity_tools()
540+
result = identity_tools.create_domain(id="domainone", name="DomainOne", description="Domain One description")
541+
542+
# Verify results
543+
assert result == Domain(id="domainone", name="DomainOne", description="Domain One description", is_enabled=False)
544+
545+
# Verify mock calls
546+
mock_conn.identity.create_domain.assert_called_once_with(id="domainone", name="DomainOne", description="Domain One description", is_enabled=False)
547+
548+

0 commit comments

Comments
 (0)