Skip to content

Commit 2f39336

Browse files
shridhargadekarpbrezina
authored andcommitted
Adcli: Adding adcli class
Adding adcli class, and methods including info, discovery, join
1 parent ae7bc47 commit 2f39336

2 files changed

Lines changed: 206 additions & 0 deletions

File tree

sssd_test_framework/roles/client.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from ..hosts.client import ClientHost
88
from ..topology import SSSDTopologyMark
9+
from ..utils.adcli import AdcliUtils
910
from ..utils.automount import AutomountUtils
1011
from ..utils.ldb import LDBUtils
1112
from ..utils.local_users import LocalUsersUtils
@@ -59,6 +60,11 @@ def __init__(self, *args, **kwargs) -> None:
5960
Call commands from realm.
6061
"""
6162

63+
self.adcli: AdcliUtils = AdcliUtils(self.host)
64+
"""
65+
Call commands from adcli.
66+
"""
67+
6268
self.ldb: LDBUtils = LDBUtils(self.host)
6369
"""
6470
Utility for ldb functions.

sssd_test_framework/utils/adcli.py

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
"""Perform actions on Active Directory."""
2+
3+
from __future__ import annotations
4+
5+
from pytest_mh import MultihostHost, MultihostUtility
6+
from pytest_mh.conn import ProcessResult
7+
8+
__all__ = [
9+
"AdcliUtils",
10+
]
11+
12+
13+
class AdcliUtils(MultihostUtility[MultihostHost]):
14+
"""
15+
Interface to adcli utility.
16+
17+
.. code-block:: python
18+
:caption: Example usage
19+
20+
@pytest.mark.topology(KnownTopologyGroup.AnyAD)
21+
def test_adcli_join(client: Client, provider: GenericADProvider):
22+
cred = provider.host.adminpw
23+
r = client.adcli.join(provider.host.domain, ["--domain-controller", provider.host.hostname], password=cred)
24+
assert provider.host.domain in r.stdout, "adcli failed to join the client!"
25+
26+
.. note::
27+
28+
This utility will not revert any changes. It relies on AD host topology for clean up.
29+
For methods requiring an authentication, --stdin-password(-W) is a default. Setting krb=True will enable
30+
kerberos based authentication.
31+
"""
32+
33+
def info(self, domain: str, *, args: list[str] | None = None) -> ProcessResult:
34+
"""
35+
Discover AD domain.
36+
37+
:param domain: domain.
38+
:type domain: str
39+
:param args: additional arguments, defaults to None
40+
:type args: list[str] | None, optional
41+
:return: Result of called command.
42+
:rtype: ProcessResult
43+
"""
44+
if args is None:
45+
args = []
46+
47+
command = self.host.conn.exec(["adcli", "info", *args, "--verbose", f"{domain}"], raise_on_error=False)
48+
49+
return command
50+
51+
def testjoin(
52+
self,
53+
domain: str,
54+
*,
55+
args: list[str] | None = None,
56+
) -> ProcessResult:
57+
"""
58+
Validate join.
59+
60+
:param domain: Domain.
61+
:type domain: str
62+
:param args: Additional arguments, defaults to None
63+
:type args: list[str] | None, optional
64+
:return: Result of called command.
65+
:rtype: ProcessResult
66+
"""
67+
if args is None:
68+
args = []
69+
70+
return self.host.conn.exec(["adcli", "testjoin", "--verbose", domain, *args], raise_on_error=False)
71+
72+
def join(
73+
self,
74+
domain: str,
75+
*,
76+
args: list[str] | None = None,
77+
password: str,
78+
login_user: str,
79+
krb: bool = False,
80+
) -> ProcessResult:
81+
"""
82+
Create a computer account.
83+
84+
:param domain: Domain.
85+
:type domain: str
86+
:param args: Additional arguments, defaults to None
87+
:type args: list[str] | None, optional
88+
:param password: Password
89+
:type password: str
90+
:param login_user: Authenticating User
91+
:type login_user: str
92+
:param krb: Use Kerberos credentials, defaults to False
93+
:type krb: bool, optional
94+
:return: Result of called command.
95+
:rtype: ProcessResult
96+
"""
97+
if args is None:
98+
args = []
99+
100+
if krb:
101+
self.host.conn.exec(["kinit", f"{login_user}@{domain.upper()}"], input=password)
102+
command = self.host.conn.exec(["adcli", "join", "--verbose", "-C", *args, domain], raise_on_error=False)
103+
else:
104+
command = self.host.conn.exec(
105+
["adcli", "join", "--stdin-password", "--verbose", f"--login-user={login_user}", *args, domain],
106+
input=password,
107+
raise_on_error=False,
108+
)
109+
110+
return command
111+
112+
def delete_computer(
113+
self,
114+
domain: str,
115+
*,
116+
args: list[str] | None = None,
117+
password: str,
118+
login_user: str,
119+
krb: bool = False,
120+
) -> ProcessResult:
121+
"""
122+
Delete computer account.
123+
124+
:param domain: Domain.
125+
:type domain: str
126+
:param args: additional arguments, defaults to None.
127+
:type args: list[str] | None, optional
128+
:param password: Password
129+
:type password: str
130+
:param login_user: Authenticating User
131+
:type login_user: str
132+
:param krb: Use Kerberos credentials, defaults to False
133+
:type krb: bool, optional
134+
:return: Result of called command.
135+
:rtype: ProcessResult
136+
"""
137+
if args is None:
138+
args = []
139+
140+
if krb:
141+
self.host.conn.exec(["kinit", f"{login_user}@{domain.upper()}"], input=password)
142+
command = self.host.conn.exec(["adcli", "delete-computer", "--verbose", "-C", *args], raise_on_error=False)
143+
else:
144+
command = self.host.conn.exec(
145+
["adcli", "delete-computer", "--stdin-password", "--verbose", *args],
146+
input=password,
147+
raise_on_error=False,
148+
)
149+
150+
return command
151+
152+
def show_computer(
153+
self,
154+
domain: str,
155+
*,
156+
password: str,
157+
args: list[str] | None = None,
158+
login_user: str,
159+
krb: bool = False,
160+
) -> ProcessResult:
161+
"""
162+
Show computer.
163+
164+
:param domain: Domain.
165+
:type domain: str
166+
:param args: additional arguments, defaults to None
167+
:type args: list[str] | None, optional
168+
:param password: Password
169+
:type password: str
170+
:param login_user: Authenticating User
171+
:type login_user: str
172+
:param krb: Use Kerberos credentials, defaults to False
173+
:type krb: bool, optional
174+
:return: Result of called command.
175+
:rtype: ProcessResult
176+
"""
177+
if args is None:
178+
args = []
179+
180+
if krb:
181+
self.host.conn.exec(["kinit", f"{login_user}@{domain.upper()}"], input=password)
182+
command = self.host.conn.exec(
183+
["adcli", "show-computer", f"--domain={domain}", "--verbose", "-C", *args], raise_on_error=False
184+
)
185+
else:
186+
command = self.host.conn.exec(
187+
[
188+
"adcli",
189+
"show-computer",
190+
"--stdin-password",
191+
"-U",
192+
login_user,
193+
f"--domain={domain}",
194+
"--verbose",
195+
*args,
196+
],
197+
input=password,
198+
raise_on_error=False,
199+
)
200+
return command

0 commit comments

Comments
 (0)