-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Each action is a separate class Allows for us to share code between actions
- Loading branch information
Showing
32 changed files
with
2,323 additions
and
982 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
# Copyright 2023 Red Hat, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
|
||
import uuid | ||
from typing import Dict | ||
|
||
from ansible_rulebook.conf import settings | ||
from ansible_rulebook.event_filter.insert_meta_info import main as insert_meta | ||
from ansible_rulebook.util import run_at | ||
|
||
from .control import Control | ||
from .metadata import Metadata | ||
|
||
KEY_EDA_VARS = "ansible_eda" | ||
INTERNAL_ACTION_STATUS = "successful" | ||
|
||
|
||
class BaseAction: | ||
def __init__(self, metadata: Metadata, control: Control, action: str): | ||
self.metadata = metadata | ||
self.control = control | ||
self.uuid = str(uuid.uuid4()) | ||
self.action = action | ||
|
||
async def send(self, data: dict, objtype: str = "Action") -> None: | ||
payload = { | ||
"type": objtype, | ||
"action": self.action, | ||
"action_uuid": self.uuid, | ||
"ruleset": self.metadata.rule_set, | ||
"ruleset_uuid": self.metadata.rule_set_uuid, | ||
"rule": self.metadata.rule, | ||
"rule_uuid": self.metadata.rule_uuid, | ||
"rule_run_at": self.metadata.rule_run_at, | ||
"activation_id": settings.identifier, | ||
"activation_instance_id": settings.identifier, | ||
} | ||
payload.update(data) | ||
await self.control.event_log.put(payload) | ||
|
||
async def send_default_status(self): | ||
await self.send( | ||
{ | ||
"run_at": run_at(), | ||
"status": INTERNAL_ACTION_STATUS, | ||
"matching_events": self._get_events(), | ||
} | ||
) | ||
|
||
def _get_events(self) -> Dict: | ||
if "event" in self.control.variables: | ||
return {"m": self.control.variables["event"]} | ||
if "events" in self.control.variables: | ||
return self.control.variables["events"] | ||
return {} | ||
|
||
def _embellish_internal_event(self, event: Dict) -> Dict: | ||
return insert_meta( | ||
event, **{"source_name": self.action, "source_type": "internal"} | ||
) | ||
|
||
def set_action(self, action): | ||
self.action = action | ||
|
||
def _collect_extra_vars(self, user_extra_vars: dict) -> dict: | ||
extra_vars = user_extra_vars.copy() if user_extra_vars else {} | ||
|
||
eda_vars = { | ||
"ruleset": self.metadata.rule_set, | ||
"rule": self.metadata.rule, | ||
} | ||
if "events" in self.control.variables: | ||
eda_vars["events"] = self.control.variables["events"] | ||
if "event" in self.control.variables: | ||
eda_vars["event"] = self.control.variables["event"] | ||
|
||
extra_vars[KEY_EDA_VARS] = eda_vars | ||
return extra_vars |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Copyright 2023 Red Hat, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import asyncio | ||
from dataclasses import dataclass | ||
from typing import List | ||
|
||
|
||
@dataclass(frozen=True) | ||
class Control: | ||
__slots__ = [ | ||
"event_log", | ||
"inventory", | ||
"hosts", | ||
"variables", | ||
"project_data_file", | ||
] | ||
event_log: asyncio.Queue | ||
inventory: str | ||
hosts: List[str] | ||
variables: dict | ||
project_data_file: str |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# Copyright 2023 Red Hat, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import logging | ||
import sys | ||
from dataclasses import asdict | ||
from pprint import pprint | ||
|
||
import dpath | ||
from drools import ruleset as lang | ||
|
||
from ansible_rulebook.util import get_horizontal_rule | ||
|
||
from .base_action import BaseAction | ||
from .control import Control | ||
from .metadata import Metadata | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class Debug(BaseAction): | ||
def __init__(self, metadata: Metadata, control: Control, **action_args): | ||
super().__init__(metadata, control, "debug") | ||
self.action_args = action_args | ||
|
||
async def __call__(self): | ||
|
||
if "msg" in self.action_args: | ||
messages = self.action_args.get("msg") | ||
if not isinstance(messages, list): | ||
messages = [messages] | ||
for msg in messages: | ||
print(msg) | ||
elif "var" in self.action_args: | ||
key = self.action_args.get("var") | ||
try: | ||
print(dpath.get(self.control.variables, key, separator=".")) | ||
except KeyError: | ||
logger.error("Key %s not found in variable pool", key) | ||
raise | ||
else: | ||
print(get_horizontal_rule("=")) | ||
print("kwargs:") | ||
args = asdict(self.metadata) | ||
args.update( | ||
{ | ||
"inventory": self.control.inventory, | ||
"hosts": self.control.hosts, | ||
"variables": self.control.variables, | ||
"project_data_file": self.control.project_data_file, | ||
} | ||
) | ||
pprint(args) | ||
print(get_horizontal_rule("=")) | ||
print("facts:") | ||
pprint(lang.get_facts(self.metadata.rule_set)) | ||
print(get_horizontal_rule("=")) | ||
|
||
sys.stdout.flush() | ||
await self.send_default_status() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Copyright 2023 Red Hat, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
from dataclasses import dataclass | ||
|
||
|
||
@dataclass(frozen=True) | ||
class Metadata: | ||
__slots__ = [ | ||
"rule", | ||
"rule_uuid", | ||
"rule_set", | ||
"rule_set_uuid", | ||
"rule_run_at", | ||
] | ||
rule: str | ||
rule_uuid: str | ||
rule_set: str | ||
rule_set_uuid: str | ||
rule_run_at: str |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Copyright 2023 Red Hat, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import logging | ||
|
||
from .base_action import BaseAction | ||
from .control import Control | ||
from .metadata import Metadata | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class Noop(BaseAction): | ||
def __init__(self, metadata: Metadata, control: Control, **action_args): | ||
super().__init__(metadata, control, "noop") | ||
self.action_args = action_args | ||
|
||
async def __call__(self): | ||
await self.send_default_status() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# Copyright 2023 Red Hat, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import logging | ||
|
||
from drools import ruleset as lang | ||
|
||
from .base_action import BaseAction | ||
from .control import Control | ||
from .metadata import Metadata | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class PostEvent(BaseAction): | ||
def __init__(self, metadata: Metadata, control: Control, **action_args): | ||
super().__init__(metadata, control, "post_event") | ||
self.action_args = action_args | ||
|
||
async def __call__(self): | ||
lang.post( | ||
self.action_args["ruleset"], | ||
self._embellish_internal_event(self.action_args["event"]), | ||
) | ||
await self.send_default_status() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Copyright 2023 Red Hat, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import sys | ||
from pprint import pprint | ||
from typing import Callable | ||
|
||
from .base_action import BaseAction | ||
from .control import Control | ||
from .metadata import Metadata | ||
|
||
|
||
class PrintEvent(BaseAction): | ||
def __init__(self, metadata: Metadata, control: Control, **action_args): | ||
super().__init__(metadata, control, "print_event") | ||
|
||
self.action_args = action_args | ||
|
||
async def __call__(self): | ||
print_fn: Callable = print | ||
if "pretty" in self.action_args: | ||
print_fn = pprint | ||
|
||
var_name = "events" if "events" in self.control.variables else "event" | ||
|
||
print_fn(self.control.variables[var_name]) | ||
sys.stdout.flush() | ||
await self.send_default_status() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Copyright 2023 Red Hat, Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import logging | ||
|
||
from drools import ruleset as lang | ||
|
||
from .base_action import BaseAction | ||
from .control import Control | ||
from .metadata import Metadata | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class RetractFact(BaseAction): | ||
def __init__(self, metadata: Metadata, control: Control, **action_args): | ||
super().__init__(metadata, control, "retract_fact") | ||
self.action_args = action_args | ||
|
||
async def __call__(self): | ||
partial = self.action_args.get("partial", True) | ||
if not partial: | ||
exclude_keys = ["meta"] | ||
else: | ||
exclude_keys = [] | ||
|
||
lang.retract_matching_facts( | ||
self.action_args["ruleset"], | ||
self.action_args["fact"], | ||
partial, | ||
exclude_keys, | ||
) | ||
await self.send_default_status() |
Oops, something went wrong.