Skip to content

Commit 5d054f1

Browse files
committed
Fixed ansible pyright error and unknown function error
Fixed the way ansible promise type handldes missing ansible dependency to be compatible with pyright. Moreover, Ansible doesn't error anymore on unknown functionn init_plugin_loader() when ansible is not installed. Signed-off-by: Victor Moene <victor.moene@northern.tech>
1 parent 74be3e5 commit 5d054f1

1 file changed

Lines changed: 111 additions & 103 deletions

File tree

Lines changed: 111 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import os
22

33
from typing import Dict, Tuple, List
4-
54
from cfengine_module_library import PromiseModule, ValidationError, Result
65

76
try:
@@ -15,13 +14,6 @@
1514
from ansible.vars.manager import VariableManager
1615
from ansible.plugins.loader import init_plugin_loader
1716

18-
ANSIBLE_AVAILABLE = True
19-
except ImportError:
20-
ANSIBLE_AVAILABLE = False
21-
22-
23-
if ANSIBLE_AVAILABLE:
24-
2517
class CallbackModule(CallbackBase):
2618
CALLBACK_VERSION = 1.0
2719
CALLBACK_TYPE = "stdout"
@@ -70,101 +62,117 @@ def v2_playbook_on_stats(self, stats):
7062
"Summary of the tasks for '" + host + "' is: " + summary
7163
)
7264

65+
class AnsiblePromiseTypeModule(PromiseModule):
66+
def __init__(self, **kwargs):
67+
super(AnsiblePromiseTypeModule, self).__init__(
68+
"ansible_promise_module", "0.0.0", **kwargs
69+
)
70+
71+
def must_be_absolute(v):
72+
if not os.path.isabs(v):
73+
raise ValidationError(
74+
"Must be an absolute path, not '{v}'".format(v=v)
75+
)
76+
77+
self.add_attribute(
78+
"playbook", str, default_to_promiser=True, validator=must_be_absolute
79+
)
80+
self.add_attribute("inventory", str, validator=must_be_absolute)
81+
self.add_attribute("limit", list, default=["localhost"])
82+
self.add_attribute("tags", list, default=[])
83+
self.add_attribute("become", bool, default=False)
84+
self.add_attribute("become_method", str, default="sudo")
85+
self.add_attribute("become_user", str, default="root")
86+
self.add_attribute("connection", str, default="local")
87+
self.add_attribute("forks", int, default=1)
88+
self.add_attribute("private_key_file", str, validator=must_be_absolute)
89+
self.add_attribute("remote_user", str, default="root")
90+
91+
def prepare_promiser_and_attributes(self, promiser, attributes):
92+
safe_promiser = promiser.replace(",", "_")
93+
return (safe_promiser, attributes)
94+
95+
def validate_promise(self, promiser: str, attributes: Dict, metadata: Dict):
96+
return
97+
98+
def evaluate_promise(
99+
self, safe_promiser: str, attributes: Dict, metadata: Dict
100+
) -> Tuple[str, List[str]]:
101+
model = self.create_attribute_object(safe_promiser, attributes)
102+
103+
classes = []
104+
result = Result.KEPT
105+
106+
context.CLIARGS = ImmutableDict(
107+
tags=model.tags,
108+
listtags=False,
109+
listtasks=False,
110+
listhosts=False,
111+
syntax=False,
112+
connection=model.connection,
113+
module_path=None,
114+
remote_user=model.remote_user,
115+
private_key_file=model.private_key_file,
116+
ssh_common_args=None,
117+
ssh_extra_args=None,
118+
sftp_extra_args=None,
119+
scp_extra_args=None,
120+
become=model.become,
121+
become_method=model.become_method,
122+
become_user=model.become_user,
123+
forks=model.forks,
124+
verbosity=0,
125+
check=False,
126+
start_at_task=None,
127+
)
128+
129+
loader = DataLoader()
130+
inventory = InventoryManager(
131+
loader=loader,
132+
sources=(model.inventory,) if model.inventory else (),
133+
)
134+
135+
variable_manager = VariableManager(
136+
loader=loader,
137+
inventory=inventory,
138+
version_info=CLI.version_info(gitinfo=False),
139+
)
140+
pbex = PlaybookExecutor(
141+
playbooks=[attributes["playbook"]],
142+
inventory=inventory,
143+
variable_manager=variable_manager,
144+
loader=loader,
145+
passwords={},
146+
)
147+
callback = CallbackModule(promise=self)
148+
pbex._tqm._stdout_callback = callback # type: ignore
149+
150+
exit_code = pbex.run()
151+
if exit_code != 0:
152+
classes.append(
153+
"{safe_promiser}_failed".format(safe_promiser=safe_promiser)
154+
)
155+
result = Result.NOT_KEPT
156+
elif callback.changed:
157+
result = Result.REPAIRED
158+
159+
return (result, classes)
160+
161+
if __name__ == "__main__":
162+
init_plugin_loader()
163+
AnsiblePromiseTypeModule().start()
164+
165+
except ModuleNotFoundError:
166+
167+
class UnavailableAnsiblePromiseTypeModule(PromiseModule):
168+
169+
def __init__(self, **kwargs):
170+
super(UnavailableAnsiblePromiseTypeModule, self).__init__(
171+
"ansible_promise_module", "0.0.0", **kwargs
172+
)
73173

74-
class AnsiblePromiseTypeModule(PromiseModule):
75-
def __init__(self, **kwargs):
76-
super(AnsiblePromiseTypeModule, self).__init__(
77-
"ansible_promise_module", "0.0.0", **kwargs
78-
)
79-
80-
def must_be_absolute(v):
81-
if not os.path.isabs(v):
82-
raise ValidationError("Must be an absolute path, not '{v}'".format(v=v))
83-
84-
self.add_attribute(
85-
"playbook", str, default_to_promiser=True, validator=must_be_absolute
86-
)
87-
self.add_attribute("inventory", str, validator=must_be_absolute)
88-
self.add_attribute("limit", list, default=["localhost"])
89-
self.add_attribute("tags", list, default=[])
90-
self.add_attribute("become", bool, default=False)
91-
self.add_attribute("become_method", str, default="sudo")
92-
self.add_attribute("become_user", str, default="root")
93-
self.add_attribute("connection", str, default="local")
94-
self.add_attribute("forks", int, default=1)
95-
self.add_attribute("private_key_file", str, validator=must_be_absolute)
96-
self.add_attribute("remote_user", str, default="root")
97-
98-
def prepare_promiser_and_attributes(self, promiser, attributes):
99-
safe_promiser = promiser.replace(",", "_")
100-
return (safe_promiser, attributes)
101-
102-
def validate_promise(self, promiser: str, attributes: Dict, metadata: Dict):
103-
if not ANSIBLE_AVAILABLE:
174+
def validate_promise(self, promiser: str, attributes: Dict, metadata: Dict):
104175
raise ValidationError("Ansible Python module not available")
105176

106-
def evaluate_promise(
107-
self, safe_promiser: str, attributes: Dict, metadata: Dict
108-
) -> Tuple[str, List[str]]:
109-
model = self.create_attribute_object(safe_promiser, attributes)
110-
111-
classes = []
112-
result = Result.KEPT
113-
114-
context.CLIARGS = ImmutableDict(
115-
tags=model.tags,
116-
listtags=False,
117-
listtasks=False,
118-
listhosts=False,
119-
syntax=False,
120-
connection=model.connection,
121-
module_path=None,
122-
remote_user=model.remote_user,
123-
private_key_file=model.private_key_file,
124-
ssh_common_args=None,
125-
ssh_extra_args=None,
126-
sftp_extra_args=None,
127-
scp_extra_args=None,
128-
become=model.become,
129-
become_method=model.become_method,
130-
become_user=model.become_user,
131-
forks=model.forks,
132-
verbosity=0,
133-
check=False,
134-
start_at_task=None,
135-
)
136-
137-
loader = DataLoader()
138-
inventory = InventoryManager(
139-
loader=loader,
140-
sources=(model.inventory,) if model.inventory else (),
141-
)
142-
143-
variable_manager = VariableManager(
144-
loader=loader,
145-
inventory=inventory,
146-
version_info=CLI.version_info(gitinfo=False),
147-
)
148-
pbex = PlaybookExecutor(
149-
playbooks=[attributes["playbook"]],
150-
inventory=inventory,
151-
variable_manager=variable_manager,
152-
loader=loader,
153-
passwords={},
154-
)
155-
callback = CallbackModule(promise=self)
156-
pbex._tqm._stdout_callback = callback # type: ignore
157-
158-
exit_code = pbex.run()
159-
if exit_code != 0:
160-
classes.append("{safe_promiser}_failed".format(safe_promiser=safe_promiser))
161-
result = Result.NOT_KEPT
162-
elif callback.changed:
163-
result = Result.REPAIRED
164-
165-
return (result, classes)
166-
167-
168-
if __name__ == "__main__":
169-
init_plugin_loader()
170-
AnsiblePromiseTypeModule().start()
177+
if __name__ == "__main__":
178+
UnavailableAnsiblePromiseTypeModule().start()

0 commit comments

Comments
 (0)