From e7e9bfc0da190fb8bbb1b98734c358d771dca979 Mon Sep 17 00:00:00 2001 From: Ilya Shakhat Date: Tue, 9 Aug 2016 15:00:07 +0300 Subject: [PATCH] Add node operations --- os_failures/__init__.py | 17 +++- os_failures/api/client.py | 2 +- .../api/{node.py => node_collection.py} | 16 ++-- .../api/{service_collection.py => service.py} | 6 +- os_failures/drivers/fuel.py | 78 ++++++++++++------- os_failures/drivers/kvm.py | 3 + os_failures/tests/sample.py | 15 +++- requirements.txt | 1 + 8 files changed, 93 insertions(+), 45 deletions(-) rename os_failures/api/{node.py => node_collection.py} (61%) rename os_failures/api/{service_collection.py => service.py} (66%) create mode 100644 os_failures/drivers/kvm.py diff --git a/os_failures/__init__.py b/os_failures/__init__.py index 152878c..0555399 100644 --- a/os_failures/__init__.py +++ b/os_failures/__init__.py @@ -15,12 +15,23 @@ import pbr.version from os_failures.drivers import fuel +from os_failures.drivers import kvm __version__ = pbr.version.VersionInfo( 'os_failures').version_string() def build_client(cloud_config): - cloud_management = cloud_config.get('cloud_management') or {} - if 'fuel' in cloud_management: - return fuel.FuelClient(cloud_management['fuel']) + cloud_management = None + cloud_management_params = cloud_config.get('cloud_management') or {} + + if 'fuel' in cloud_management_params: + cloud_management = fuel.FuelClient(cloud_management_params['fuel']) + + power_management = None + power_management_params = cloud_config.get('power_management') or {} + + if 'kvm' in power_management_params: + power_management = kvm.KVM(power_management_params['kvm']) + + return cloud_management diff --git a/os_failures/api/client.py b/os_failures/api/client.py index b799722..7a218b7 100644 --- a/os_failures/api/client.py +++ b/os_failures/api/client.py @@ -9,5 +9,5 @@ class Client(object): pass @abc.abstractmethod - def get_services(self, name): + def get_service(self, name): pass diff --git a/os_failures/api/node.py b/os_failures/api/node_collection.py similarity index 61% rename from os_failures/api/node.py rename to os_failures/api/node_collection.py index 705fe14..8481def 100644 --- a/os_failures/api/node.py +++ b/os_failures/api/node_collection.py @@ -1,12 +1,10 @@ import abc +import six + +@six.add_metaclass(abc.ABCMeta) class NodeCollection(object): - __metaclass__ = abc.ABCMeta - - @abc.abstractmethod - def kill_process(self): - pass @abc.abstractmethod def oom(self): @@ -15,3 +13,11 @@ class NodeCollection(object): @abc.abstractmethod def reboot(self): pass + + @abc.abstractmethod + def pick(self): + pass + + @abc.abstractmethod + def poweroff(self): + pass diff --git a/os_failures/api/service_collection.py b/os_failures/api/service.py similarity index 66% rename from os_failures/api/service_collection.py rename to os_failures/api/service.py index 47b7af3..abe73d1 100644 --- a/os_failures/api/service_collection.py +++ b/os_failures/api/service.py @@ -1,8 +1,10 @@ import abc +import six -class ServiceCollection(object): - __metaclass__ = abc.ABCMeta + +@six.add_metaclass(abc.ABCMeta) +class Service(object): @abc.abstractmethod def get_nodes(self): diff --git a/os_failures/drivers/fuel.py b/os_failures/drivers/fuel.py index 97b3a2e..01de206 100644 --- a/os_failures/drivers/fuel.py +++ b/os_failures/drivers/fuel.py @@ -1,9 +1,10 @@ import json +import random from os_failures.ansible import runner -from os_failures.api import client -from os_failures.api import node -from os_failures.api import service_collection +from os_failures.api import client as client_pkg +from os_failures.api import node_collection +from os_failures.api import service ROLE_MAPPING = { @@ -11,65 +12,82 @@ ROLE_MAPPING = { } -class FuelNodes(node.NodeCollection): - def __init__(self, client=None, collection=None): +class FuelNodes(node_collection.NodeCollection): + def __init__(self, client=None, hosts=None): self.client = client + self.hosts = hosts def reboot(self): - print('Reboot!') + task = { + 'command': 'ps aux' + } + self.client.execute_on_cloud(self.hosts, task) def oom(self): print('OOM!') - def kill_process(self): - print('PS') + def pick(self): + return FuelNodes(self.client, random.choice(self.hosts)) + + def poweroff(self): + super(FuelNodes, self).poweroff() -class FuelService(service_collection.ServiceCollection): +class FuelService(service.Service): def __init__(self, client=None, name=None): self.client = client self.name = name + def _get_hosts(self): + cloud_hosts = self.client.get_cloud_hosts() + return [n['ip'] for n in cloud_hosts if 'controller' in n['roles']] + def get_nodes(self): if self.name == 'keystone-api': - nodes = self.client.get_fuel_nodes() - controllers = [n for n in nodes if 'controller' in n['roles']] - return FuelNodes(client=self.client, collection=controllers) - pass + hosts = self._get_hosts() + return FuelNodes(client=self.client, hosts=hosts) def stop(self): - super(FuelService, self).stop() + if self.name == 'keystone-api': + task = { + 'command': 'service apache2 restart' + } + print(self.client.execute_on_cloud(self._get_hosts(), task)) -class FuelClient(client.Client): +class FuelClient(client_pkg.Client): def __init__(self, params): - self.ip = params['ip'] + self.master_node_address = params['master_node_host'] self.username = params['username'] self.password = params['password'] - self.ansible_executor = runner.AnsibleRunner( + self.master_node_executor = runner.AnsibleRunner( remote_user=self.username) - task = {'command': 'fuel2 node list -f json'} - nodes_s = self.ansible_executor.execute([self.ip], task) - nodes = json.loads(nodes_s[0]['payload']['stdout']) - print(nodes) + print(self.get_cloud_hosts()) - self.ansible_executor = runner.AnsibleRunner( + self.cloud_executor = runner.AnsibleRunner( remote_user=self.username, - ssh_common_args='-o ProxyCommand="ssh -W %h:%p root@172.18.171.149"') + ssh_common_args='-o ProxyCommand="ssh -W %%h:%%p %s@%s"' % + (self.username, self.master_node_address)) task = {'command': 'hostname'} - print(self.ansible_executor.execute(['10.20.0.3', '10.20.0.4'], task)) + print(self.execute_on_cloud(['10.20.0.3', '10.20.0.4'], task)) - def get_fuel_nodes(self): + def get_cloud_hosts(self): task = {'command': 'fuel2 node list -f json'} - nodes_s = self.ansible_executor.execute([self.ip], task) - nodes = json.loads(nodes_s[0]['payload']['stdout']) - return nodes + r = self.execute_on_master_node(task) + return json.loads(r[0]['payload']['stdout']) + + def execute_on_master_node(self, task): + return self.master_node_executor.execute([self.master_node_address], task) + + def execute_on_cloud(self, hosts, task): + return self.cloud_executor.execute(hosts, task) def get_nodes(self): - pass + hosts = self.get_cloud_hosts() + return FuelNodes(client=self, hosts=hosts) - def get_services(self, name): + def get_service(self, name): return FuelService(client=self, name=name) diff --git a/os_failures/drivers/kvm.py b/os_failures/drivers/kvm.py new file mode 100644 index 0000000..8e343d4 --- /dev/null +++ b/os_failures/drivers/kvm.py @@ -0,0 +1,3 @@ +class KVM(object): + def __init__(self, params): + super(KVM, self).__init__() \ No newline at end of file diff --git a/os_failures/tests/sample.py b/os_failures/tests/sample.py index 2424f54..2c33cd6 100644 --- a/os_failures/tests/sample.py +++ b/os_failures/tests/sample.py @@ -23,16 +23,23 @@ def main(): 'region_name': 'RegionOne', 'cloud_management': { 'fuel': { - 'ip': '172.18.171.149', + 'master_node_host': '172.18.171.149', 'username': 'root', 'password': 'r00tme', } } } client = os_failures.build_client(cloud_config) - services = client.get_services(name='keystone-api') - print(services) - services.get_nodes().reboot() + service = client.get_service(name='keystone-api') + print(service) + service.stop() + + nodes = service.get_nodes() + print(nodes) + nodes.reboot() + + one = nodes.pick() + one.poweroff() if __name__ == '__main__': diff --git a/requirements.txt b/requirements.txt index 6be2327..0df8444 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,3 +10,4 @@ oslo.i18n>=1.5.0 # Apache-2.0 oslo.log>=1.12.0 # Apache-2.0 oslo.serialization>=1.10.0 # Apache-2.0 oslo.utils!=2.6.0,>=2.4.0 # Apache-2.0 +six>=1.9.0