Skip to content

Commit

Permalink
Pythonize "rookify" application (#22)
Browse files Browse the repository at this point in the history
Signed-off-by: Tobias Wolf <[email protected]>
Co-authored-by: Jan-Marten Brüggemann <[email protected]>
  • Loading branch information
NotTheEvilOne and brueggemann authored Mar 1, 2024
1 parent 7ea96af commit 915e296
Show file tree
Hide file tree
Showing 13 changed files with 74 additions and 49 deletions.
4 changes: 0 additions & 4 deletions src/modules/migrate_monitors/main.py

This file was deleted.

26 changes: 9 additions & 17 deletions src/rookify.py → src/rookify/__main__.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import modules
import yaml
from types import MappingProxyType

def load_yaml(path: str) -> dict:
with open(path, 'r') as file:
return yaml.safe_load(file)
import rookify.modules

def save_yaml(path: str, data: dict) -> None:
with open(path, 'w') as file:
yaml.safe_dump(data, file)
from types import MappingProxyType
from .yaml import load_yaml, save_yaml

def main():

try:
config = load_yaml("config.yaml")
except FileNotFoundError as err:
raise SystemExit(f'Could not load config: {err}')
migration_modules = modules.load_modules(config['migration_modules'])
migration_modules = rookify.modules.load_modules(config['migration_modules'])

module_data = dict()
try:
Expand All @@ -36,7 +28,7 @@ def main():
module_data[module.__name__] = result
else:
handlers.append((module, handler))

# Do preflight check of all other handlers
for module, handler in handlers:
handler.preflight_check()
Expand All @@ -45,8 +37,8 @@ def main():
for module, handler in handlers:
result = handler.run()
module_data[module.__name__] = result

save_yaml(config['general']['module_data_file'], module_data)

if __name__ == "__main__":
main()
main()
17 changes: 10 additions & 7 deletions src/modules/__init__.py → src/rookify/modules/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# -*- coding: utf-8 -*-

import functools
import importlib

from typing import Optional
from collections import OrderedDict
from modules.module import ModuleHandler
import functools
from .module import ModuleHandler

class ModuleLoadException(Exception):
"""
Expand Down Expand Up @@ -32,7 +35,7 @@ def load_required_modules(module_names: list, modules: OrderedDict) -> None:
if module_name in modules:
continue

module = importlib.import_module(f"modules.{module_name}")
module = importlib.import_module(f"rookify.modules.{module_name}")

for attr_type, attr_name in (
(ModuleHandler, 'HANDLER_CLASS'),
Expand All @@ -42,7 +45,7 @@ def load_required_modules(module_names: list, modules: OrderedDict) -> None:
):
if not hasattr(module, attr_name):
raise ModuleLoadException(module_name, f'Module has no attribute {attr_name}')

attr = getattr(module, attr_name)
if not isinstance(attr, attr_type) and not issubclass(attr, attr_type):
raise ModuleLoadException(module_name, f'Attribute {attr_name} is not type {attr_type}')
Expand All @@ -65,8 +68,8 @@ def sort_modules(modules_in: OrderedDict, modules_out: OrderedDict, module_names

after_modules_name = modules_in[module_name].AFTER
sort_modules(modules_in, modules_out, after_modules_name)

modules_out[module_name] = modules_in[module_name]
sort_modules(required_modules, modules, list(required_modules.keys()))
return list(modules.values())

return list(modules.values())
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-

from .main import AnalyzeCephHandler

HANDLER_CLASS = AnalyzeCephHandler
RUN_IN_PREFLIGHT = True
REQUIRES = []
AFTER = []
AFTER = []
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
from modules.module import ModuleHandler
# -*- coding: utf-8 -*-

import json

from ..module import ModuleHandler

class AnalyzeCephHandler(ModuleHandler):

def run(self) -> dict:

commands = [
Expand Down Expand Up @@ -30,6 +34,5 @@ def run(self) -> dict:
results['ssh']['osd'][node] = {
'devices': devices
}

return results

Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-

from .main import ExampleHandler

HANDLER_CLASS = ExampleHandler # Define the handler class for this module
RUN_IN_PREFLIGHT = False # This executes the run method during preflight checks. This is neccessary for analyze modules.
REQUIRES = ['analyze_ceph'] # A list of modules that are required to run before this module. Modules in this list will be imported, even if they are not configured
AFTER = ['migrate_monitors'] # A list of modules that should be run before this module, if they are defined in config
AFTER = ['migrate_monitors'] # A list of modules that should be run before this module, if they are defined in config
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from modules.module import ModuleHandler, ModuleException
# -*- coding: utf-8 -*-

from ..module import ModuleHandler, ModuleException

class ExampleHandler(ModuleHandler):

def preflight_check(self):
# Do something for checking if all needed preconditions are met else throw ModuleException
raise ModuleException('Example module was loaded, so aborting!')

def run(self) -> dict:
# Run the migration tasks
pass
pass
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-

from .main import MigrateMonitorsHandler

HANDLER_CLASS = MigrateMonitorsHandler
RUN_IN_PREFLIGHT = False
REQUIRES = ['analyze_ceph']
AFTER = []
AFTER = []
6 changes: 6 additions & 0 deletions src/rookify/modules/migrate_monitors/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-

from ..module import ModuleHandler

class MigrateMonitorsHandler(ModuleHandler):
pass
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-

from .main import MigrateOSDsHandler

HANDLER_CLASS = MigrateOSDsHandler
RUN_IN_PREFLIGHT = False
REQUIRES = ['analyze_ceph']
AFTER = ['migrate_monitors']
AFTER = ['migrate_monitors']
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
from modules.module import ModuleHandler, ModuleException
# -*- coding: utf-8 -*-

from ..module import ModuleHandler, ModuleException

class MigrateOSDsHandler(ModuleHandler):

def preflight_check(self):
result = self.ceph.mon_command('osd dump')
#raise ModuleException('test error')

def run(self) -> dict:
osd_config = dict()
for node, osds in self._data['modules.analyze_ceph']['node']['ls']['osd'].items():
osd_config[node] = {'osds': {}}
for osd in osds:
osd_config[node]['osds'][osd] = dict()


for osd in self._data['modules.analyze_ceph']['osd']['dump']['osds']:
number = osd['osd']
uuid = osd['uuid']
Expand Down
16 changes: 9 additions & 7 deletions src/modules/module.py → src/rookify/modules/module.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-

import json
import abc
import rados
Expand All @@ -19,7 +21,7 @@ def __init__(self, config: dict):
self.__ceph.connect()
except rados.ObjectNotFound as err:
raise ModuleException(f'Could not connect to ceph: {err}')

def mon_command(self, command: str, **kwargs) -> dict:
cmd = {
'prefix': command,
Expand All @@ -37,11 +39,11 @@ def __init__(self, config: dict):
k8s_config.api_key = config['api_key']
k8s_config.host = config['host']
self.__client = kubernetes.client.ApiClient(k8s_config)

@property
def CoreV1Api(self) -> kubernetes.client.CoreV1Api:
return kubernetes.client.CoreV1Api(self.__client)

@property
def AppsV1Api(self) -> kubernetes.client.AppsV1Api:
return kubernetes.client.AppsV1Api(self.__client)
Expand All @@ -53,7 +55,7 @@ def NodeV1Api(self) -> kubernetes.client.NodeV1Api:
class __SSH:
def __init__(self, config: dict):
self.__config = config

def command(self, host: str, command: str) -> fabric.runners.Result:
try:
address = self.__config['hosts'][host]['address']
Expand All @@ -65,7 +67,7 @@ def command(self, host: str, command: str) -> fabric.runners.Result:
connect_kwargs = {'key_filename': private_key}
result = fabric.Connection(address, user=user, port=port, connect_kwargs=connect_kwargs).run(command, hide=True)
return result

def __init__(self, config: dict, data: dict):
"""
Construct a new 'ModuleHandler' object.
Expand Down Expand Up @@ -100,7 +102,7 @@ def ceph(self) -> __Ceph:
if self.__ceph == None:
self.__ceph = self.__Ceph(self._config['ceph'])
return self.__ceph

@property
def k8s(self) -> __K8s:
if self.__k8s == None:
Expand All @@ -111,4 +113,4 @@ def k8s(self) -> __K8s:
def ssh(self) -> __SSH:
if self.__ssh == None:
self.__ssh = self.__SSH(self._config['ssh'])
return self.__ssh
return self.__ssh
11 changes: 11 additions & 0 deletions src/rookify/yaml.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-

import yaml

def load_yaml(path: str) -> dict:
with open(path, 'r') as file:
return yaml.safe_load(file)

def save_yaml(path: str, data: dict) -> None:
with open(path, 'w') as file:
yaml.safe_dump(data, file)

0 comments on commit 915e296

Please sign in to comment.