Auto discover the domain at start

`realm discover` without a domain name attempts to find one from DHCP.
This attempts to run it from the controller start method.
Only creates the discover task if there is support
Avoids exception on controller start.
This commit is contained in:
Carlos Nihelton 2023-02-16 10:21:10 -03:00
parent a37b5e3870
commit 9b50c8db07
No known key found for this signature in database
GPG Key ID: 6FE346D245197E9A
2 changed files with 27 additions and 4 deletions

View File

@ -13,6 +13,7 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import asyncio
import logging import logging
import os import os
import re import re
@ -54,6 +55,18 @@ class DcPingStrategy:
return AdDomainNameValidation.OK return AdDomainNameValidation.OK
async def discover(self) -> str:
""" Attempts to discover a domain through the network.
Returns the domain or an empty string on error. """
cp = await arun_command([self.cmd, self.arg], env={})
discovered = ""
if cp.returncode == 0:
# A typical output looks like:
# 'creative.com\n type: kerberos\n realm-name: CREATIVE.COM\n...'
discovered = cp.stdout.split('\n')[0].strip()
return discovered
class StubDcPingStrategy(DcPingStrategy): class StubDcPingStrategy(DcPingStrategy):
""" For testing purpose. This class doesn't talk to the network. """ For testing purpose. This class doesn't talk to the network.
@ -67,6 +80,9 @@ class StubDcPingStrategy(DcPingStrategy):
return AdDomainNameValidation.OK return AdDomainNameValidation.OK
async def discover(self) -> str:
return "ubuntu.com"
def has_support(self) -> bool: def has_support(self) -> bool:
return True return True
@ -84,6 +100,15 @@ class ADController(SubiquityController):
else: else:
self.ping_strgy = DcPingStrategy() self.ping_strgy = DcPingStrategy()
def start(self):
if self.ping_strgy.has_support():
asyncio.create_task(self._try_discover_domain())
async def _try_discover_domain(self):
discovered_domain = await self.ping_strgy.discover()
if discovered_domain:
self.model.set_domain(discovered_domain)
async def GET(self) -> Optional[ADConnectionInfo]: async def GET(self) -> Optional[ADConnectionInfo]:
"""Returns the currently configured AD settings""" """Returns the currently configured AD settings"""
return self.model.conn_info return self.model.conn_info
@ -116,8 +141,6 @@ class ADController(SubiquityController):
to configure AD are present in the live system.""" to configure AD are present in the live system."""
return self.ping_strgy.has_support() return self.ping_strgy.has_support()
# async def discover_domain_controller(self) -> str:
# Helper out-of-class functions grouped. # Helper out-of-class functions grouped.
class AdValidators: class AdValidators:

View File

@ -1659,8 +1659,8 @@ class TestActiveDirectory(TestAPI):
async with start_server('examples/simple.json') as instance: async with start_server('examples/simple.json') as instance:
endpoint = '/active_directory' endpoint = '/active_directory'
ad_dict = await instance.get(endpoint) ad_dict = await instance.get(endpoint)
# Starts empty # Starts with the detected domain.
self.assertIsNone(ad_dict) self.assertEqual('ubuntu.com', ad_dict['domain_name'])
# Post works by "returning None" # Post works by "returning None"
ad_dict = { ad_dict = {