Merge pull request #1550 from CarlosNihelton/ad-api-deeng-576
Active Directory API Part 1
This commit is contained in:
commit
7e2ceb9f94
|
@ -25,6 +25,8 @@ from subiquitycore.models.network import (
|
|||
|
||||
from subiquity.common.api.defs import api, Payload, simple_endpoint
|
||||
from subiquity.common.types import (
|
||||
ADValidationResult,
|
||||
ADConnectionInfo,
|
||||
AddPartitionV2,
|
||||
AnyStep,
|
||||
ApplicationState,
|
||||
|
@ -403,6 +405,16 @@ class API:
|
|||
class integrity:
|
||||
def GET() -> CasperMd5Results: ...
|
||||
|
||||
class active_directory:
|
||||
def GET() -> Optional[ADConnectionInfo]: ...
|
||||
# POST must validate the payload before configuring the controller,
|
||||
# which may contain several errors as described in [ADValidationResult]
|
||||
# simultaneously - such as invalid chars on the admin name and DC name
|
||||
# starting with a hyphen or a dot. Thus this must returns a List
|
||||
# of errors [ADValidationResult.OK] on success.
|
||||
def POST(data: Payload[ADConnectionInfo]) \
|
||||
-> List[ADValidationResult]: ...
|
||||
|
||||
|
||||
class LinkAction(enum.Enum):
|
||||
NEW = enum.auto()
|
||||
|
|
|
@ -745,3 +745,21 @@ class MirrorCheckResponse:
|
|||
url: str
|
||||
status: MirrorCheckStatus
|
||||
output: str
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True)
|
||||
class ADConnectionInfo:
|
||||
admin_name: str = ""
|
||||
domain_name: str = ""
|
||||
password: str = attr.ib(repr=False, default="")
|
||||
|
||||
|
||||
class ADValidationResult(enum.Enum):
|
||||
OK = enum.auto()
|
||||
ADMIN_NAME_BAD_FIRST_CHAR = enum.auto()
|
||||
ADMIN_NAME_BAD_CHARS = enum.auto()
|
||||
DCNAME_BAD_CHARS = enum.auto()
|
||||
DCNAME_BAD_HYPHEN = enum.auto()
|
||||
DCNAME_BAD_DOTS = enum.auto()
|
||||
DCNAME_BAD_LENGTH = enum.auto()
|
||||
PASSWORD_EMPTY = enum.auto()
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
# Copyright 2023 Canonical, Ltd.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from subiquity.common.types import ADConnectionInfo
|
||||
|
||||
log = logging.getLogger('subiquity.models.ad')
|
||||
|
||||
|
||||
class ADModel:
|
||||
""" Models the Active Directory feature """
|
||||
def __init__(self) -> None:
|
||||
self.do_join = False
|
||||
self.conn_info: Optional[ADConnectionInfo] = None
|
||||
|
||||
async def target_packages(self):
|
||||
# NOTE Those packages must be present in the target system to allow
|
||||
# joining to a domain.
|
||||
if self.do_join:
|
||||
return ["adcli", "realmd", "sssd"]
|
||||
|
||||
return []
|
|
@ -46,6 +46,7 @@ from subiquitycore.lsb_release import lsb_release
|
|||
from subiquity.common.resources import get_users_and_groups
|
||||
from subiquity.server.types import InstallerChannels
|
||||
|
||||
from .ad import ADModel
|
||||
from .codecs import CodecsModel
|
||||
from .drivers import DriversModel
|
||||
from .filesystem import FilesystemModel
|
||||
|
@ -175,6 +176,7 @@ class SubiquityModel:
|
|||
self.target = root
|
||||
self.chroot_prefix = []
|
||||
|
||||
self.ad = ADModel()
|
||||
self.codecs = CodecsModel()
|
||||
self.debconf_selections = DebconfSelectionsModel()
|
||||
self.drivers = DriversModel()
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# 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/>.
|
||||
|
||||
from .ad import ADController
|
||||
from .cmdlist import EarlyController, LateController, ErrorController
|
||||
from .codecs import CodecsController
|
||||
from .debconf import DebconfController
|
||||
|
@ -41,6 +42,7 @@ from .userdata import UserdataController
|
|||
from .zdev import ZdevController
|
||||
|
||||
__all__ = [
|
||||
'ADController',
|
||||
'CodecsController',
|
||||
'DebconfController',
|
||||
'DriversController',
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
# Copyright 2023 Canonical, Ltd.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
import logging
|
||||
from typing import List, Optional
|
||||
|
||||
from subiquity.common.apidef import API
|
||||
from subiquity.common.types import ADConnectionInfo, ADValidationResult
|
||||
from subiquity.server.controller import SubiquityController
|
||||
|
||||
log = logging.getLogger('subiquity.server.controllers.ad')
|
||||
|
||||
|
||||
class ADController(SubiquityController):
|
||||
""" Implements the server part of the Active Directory feature. """
|
||||
model_name = "ad"
|
||||
endpoint = API.active_directory
|
||||
# No auto install key and schema for now due password handling uncertainty.
|
||||
|
||||
async def GET(self) -> Optional[ADConnectionInfo]:
|
||||
"""Returns the currently configured AD settings"""
|
||||
return self.model.conn_info
|
||||
|
||||
async def POST(self, data: ADConnectionInfo) -> List[ADValidationResult]:
|
||||
self.model.conn_info = data
|
||||
await self.configured()
|
||||
return [ADValidationResult.OK]
|
|
@ -256,6 +256,7 @@ class SubiquityServer(Application):
|
|||
"Identity",
|
||||
"SSH",
|
||||
"SnapList",
|
||||
"AD",
|
||||
"Codecs",
|
||||
"Drivers",
|
||||
"TimeZone",
|
||||
|
|
|
@ -1632,3 +1632,22 @@ class TestWSLSetupOptions(TestAPI):
|
|||
|
||||
resp = await inst.get(endpoint)
|
||||
self.assertFalse(resp['install_language_support_packages'])
|
||||
|
||||
|
||||
class TestActiveDirectory(TestAPI):
|
||||
@timeout()
|
||||
async def test_ad(self):
|
||||
async with start_server('examples/simple.json') as instance:
|
||||
endpoint = '/active_directory'
|
||||
ad_dict = await instance.get(endpoint)
|
||||
# Starts empty
|
||||
self.assertIsNone(ad_dict)
|
||||
|
||||
# POST succeeds
|
||||
ad_dict = {
|
||||
'domain_name': 'ubuntu.com',
|
||||
'admin_name': 'u',
|
||||
'password': 'u'
|
||||
}
|
||||
result = await instance.post(endpoint, ad_dict)
|
||||
self.assertEqual(['OK'], result)
|
||||
|
|
Loading…
Reference in New Issue