create data-api to access current deploy state
This commit creates the api to access the deploy state and deploy host state. Test plan: PASS: Methods working and saving at software.json Story: 2010676 Task: 49037 Change-Id: I25c542e9cac07c781790652ed01921181ad1916c Signed-off-by: Luis Eduardo Bonatti <LuizEduardo.Bonatti@windriver.com>
This commit is contained in:
0
software/software/db/__init__.py
Normal file
0
software/software/db/__init__.py
Normal file
54
software/software/db/api.py
Normal file
54
software/software/db/api.py
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
from software.software_entities import DeployHandler
|
||||||
|
from software.software_entities import DeployHostHandler
|
||||||
|
|
||||||
|
def get_instance():
|
||||||
|
"""Return a Software API instance."""
|
||||||
|
return SoftwareAPI()
|
||||||
|
|
||||||
|
class SoftwareAPI:
|
||||||
|
_instance = None
|
||||||
|
|
||||||
|
def __new__(cls):
|
||||||
|
if cls._instance is None:
|
||||||
|
cls._instance = super(SoftwareAPI, cls).__new__(cls)
|
||||||
|
return cls._instance
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.deploy_handler = DeployHandler()
|
||||||
|
self.deploy_host_handler = DeployHostHandler()
|
||||||
|
|
||||||
|
def create_deploy(self, from_release, to_release, reboot_required):
|
||||||
|
self.deploy_handler.create(from_release, to_release, reboot_required)
|
||||||
|
|
||||||
|
def get_deploy(self, from_release, to_release):
|
||||||
|
return self.deploy_handler.query(from_release, to_release)
|
||||||
|
|
||||||
|
def get_deploy_all(self):
|
||||||
|
return self.deploy_handler.query_all()
|
||||||
|
|
||||||
|
def update_deploy(self, from_release, to_release, reboot_required, state):
|
||||||
|
self.deploy_handler.update(from_release, to_release, reboot_required, state)
|
||||||
|
|
||||||
|
def delete_deploy(self, from_release, to_release):
|
||||||
|
self.deploy_handler.delete(from_release, to_release)
|
||||||
|
|
||||||
|
def create_deploy_host(self, hostname, software_release, target_release):
|
||||||
|
self.deploy_host_handler.create(hostname, software_release, target_release)
|
||||||
|
|
||||||
|
def get_deploy_host_by_hostname(self, hostname):
|
||||||
|
return self.deploy_host_handler.query_by_hostname(hostname)
|
||||||
|
|
||||||
|
def get_deploy_host(self):
|
||||||
|
return self.deploy_host_handler.query_all()
|
||||||
|
|
||||||
|
def update_deploy_host(self, hostname, software_release, target_release, state):
|
||||||
|
self.deploy_host_handler.update(hostname, software_release, target_release, state)
|
||||||
|
|
||||||
|
def delete_deploy_host_by_hostname(self, hostname):
|
||||||
|
self.deploy_host_handler.delete_by_hostname(hostname)
|
||||||
|
|
||||||
|
def delete_deploy_host(self, hostname, software_release, target_release):
|
||||||
|
self.deploy_host_handler.delete(hostname, software_release, target_release)
|
||||||
|
|
||||||
|
def delete_deploy_host_all(self):
|
||||||
|
self.deploy_host_handler.delete_all()
|
@@ -95,3 +95,15 @@ class SysinvClientNotInitialized(SoftwareError):
|
|||||||
class StateValidationFailure(SoftwareError):
|
class StateValidationFailure(SoftwareError):
|
||||||
"""State Validation Failure"""
|
"""State Validation Failure"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class DeployDoNotExist(SoftwareError):
|
||||||
|
"""Deploy Do Not Exist"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
class DeployAlreadyExist(SoftwareError):
|
||||||
|
"""Deploy Already Exist"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
class ReleaseVersionDoNotExist(SoftwareError):
|
||||||
|
"""Release Version Do Not Exist"""
|
||||||
|
pass
|
||||||
|
@@ -10,7 +10,9 @@ from abc import ABC, abstractmethod
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from software.utils import check_instances, check_state
|
from software import constants
|
||||||
|
from software.exceptions import DeployDoNotExist, DeployAlreadyExist
|
||||||
|
from software.utils import check_instances, check_state, save_to_json_file, get_software_filesystem_data
|
||||||
|
|
||||||
LOG = logging.getLogger('main_logger')
|
LOG = logging.getLogger('main_logger')
|
||||||
|
|
||||||
@@ -130,17 +132,22 @@ class Deploy(ABC):
|
|||||||
'upgrade-hosts')
|
'upgrade-hosts')
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def create(self, from_release: str, to_release: str, state: str):
|
def create(self, from_release: str, to_release: str, reboot_required:bool, state: str):
|
||||||
"""
|
"""
|
||||||
Create a new deployment entry.
|
Create a new deployment entry.
|
||||||
|
|
||||||
:param from_release: The source release version.
|
:param from_release: The source release version.
|
||||||
:param to_release: The target release version.
|
:param to_release: The target release version.
|
||||||
|
:param reboot_required: If is required to do host reboot.
|
||||||
:param state: The state of the deployment.
|
:param state: The state of the deployment.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
check_instances([from_release, to_release, state], str)
|
instances = [from_release, to_release]
|
||||||
check_state(state, self.states)
|
if state:
|
||||||
|
check_state(state, self.states)
|
||||||
|
instances.append(state)
|
||||||
|
check_instances([reboot_required], bool)
|
||||||
|
check_instances(instances, str)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@@ -156,16 +163,18 @@ class Deploy(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def update(self, from_release: str, to_release: str, state: str):
|
def update(self, from_release: str, to_release: str, reboot_required:bool, state: str):
|
||||||
"""
|
"""
|
||||||
Update a deployment entry.
|
Update a deployment entry.
|
||||||
|
|
||||||
:param from_release: The source release version.
|
:param from_release: The source release version.
|
||||||
:param to_release: The target release version.
|
:param to_release: The target release version.
|
||||||
|
:param reboot_required: If is required to do host reboot.
|
||||||
:param state: The state of the deployment.
|
:param state: The state of the deployment.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
check_instances([from_release, to_release, state], str)
|
check_instances([from_release, to_release, state], str)
|
||||||
|
check_instances([reboot_required], bool)
|
||||||
check_state(state, self.states)
|
check_state(state, self.states)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -187,51 +196,225 @@ class DeployHosts(ABC):
|
|||||||
self.states = Enum('States', 'completed failed pending ready')
|
self.states = Enum('States', 'completed failed pending ready')
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def create(self, host_name: str, software_release: str, target_release: str, state: str):
|
def create(self, hostname: str, software_release: str, target_release: str, state: str):
|
||||||
"""
|
"""
|
||||||
Create a new deploy-host entry
|
Create a new deploy-host entry
|
||||||
|
|
||||||
:param host_name: The name of the host.
|
:param hostname: The name of the host.
|
||||||
:param software_release: The software release version.
|
:param software_release: The software release version.
|
||||||
:param target_release: The target release version.
|
:param target_release: The target release version.
|
||||||
:param state: The state of the deploy-host entry.
|
:param state: The state of the deploy-host entry.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
check_instances([host_name, software_release, target_release, state], str)
|
instances = [hostname, software_release, target_release]
|
||||||
check_state(state, self.states)
|
if state:
|
||||||
|
check_state(state, self.states)
|
||||||
|
instances.append(state)
|
||||||
|
check_instances(instances, str)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def query(self, host_name: str):
|
def query_by_hostname(self, hostname: str):
|
||||||
"""
|
"""
|
||||||
Get deploy-host entries for a given host.
|
Get deploy-host entries for a given host.
|
||||||
|
|
||||||
:param host_name: The name of the host.
|
:param hostname: The name of the host.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
check_instances([host_name], str)
|
check_instances([hostname], str)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def update(self, host_name: str, software_release: str, target_release: str, state: str):
|
def query(self, hostname: str, software_release: str, target_release: str):
|
||||||
"""
|
"""
|
||||||
update a deploy-host entry
|
Get deploy-host entries for a given host.
|
||||||
|
|
||||||
:param host_name: The name of the host.
|
:param hostname: The name of the host.
|
||||||
|
:param software_release: The software release version.
|
||||||
|
:param target_release: The target release version.
|
||||||
|
|
||||||
|
"""
|
||||||
|
check_instances([hostname, software_release, target_release], str)
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def update(self, hostname: str, software_release: str, target_release: str, state: str):
|
||||||
|
"""
|
||||||
|
Update a deploy-host entry
|
||||||
|
|
||||||
|
:param hostname: The name of the host.
|
||||||
:param software_release: The software release version.
|
:param software_release: The software release version.
|
||||||
:param target_release: The target release version.
|
:param target_release: The target release version.
|
||||||
:param state: The state of the deploy-host entry.
|
:param state: The state of the deploy-host entry.
|
||||||
"""
|
"""
|
||||||
check_instances([host_name, software_release, target_release, state], str)
|
check_instances([hostname, software_release, target_release, state], str)
|
||||||
check_state(state, self.states)
|
check_state(state, self.states)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def delete(self, host_name: str):
|
def delete_by_hostname(self, hostname: str):
|
||||||
"""
|
"""
|
||||||
Delete deploy-host entries for a given host.
|
Delete deploy-host entries for a given host.
|
||||||
|
|
||||||
:param host_name: The name of the host.
|
:param hostname: The name of the host.
|
||||||
"""
|
"""
|
||||||
check_instances([host_name], str)
|
check_instances([hostname], str)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def delete(self, hostname, software_release, target_release):
|
||||||
|
"""
|
||||||
|
Delete deploy-host entries for a given host.
|
||||||
|
|
||||||
|
:param hostname: The name of the host.
|
||||||
|
:param software_release: The software release version.
|
||||||
|
:param target_release: The target release version.
|
||||||
|
"""
|
||||||
|
check_instances([hostname, software_release, target_release], str)
|
||||||
|
pass
|
||||||
|
|
||||||
|
class DeployHandler(Deploy):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.data = get_software_filesystem_data()
|
||||||
|
|
||||||
|
def create(self, from_release, to_release, reboot_required, state=None):
|
||||||
|
super().create(from_release, to_release, reboot_required, state)
|
||||||
|
deploy = self.query(from_release, to_release)
|
||||||
|
if deploy:
|
||||||
|
raise DeployAlreadyExist("Error to create. Deploy already exist.")
|
||||||
|
new_deploy = {
|
||||||
|
"from_release": from_release,
|
||||||
|
"to_release": to_release,
|
||||||
|
"reboot_required": reboot_required,
|
||||||
|
"state": state
|
||||||
|
}
|
||||||
|
deploy_data = self.data.get("deploy", [])
|
||||||
|
if not deploy_data:
|
||||||
|
deploy_data = {
|
||||||
|
"deploy": []
|
||||||
|
}
|
||||||
|
deploy_data["deploy"].append(new_deploy)
|
||||||
|
self.data.update(deploy_data)
|
||||||
|
else:
|
||||||
|
deploy_data.append(new_deploy)
|
||||||
|
save_to_json_file(constants.SOFTWARE_JSON_FILE, self.data)
|
||||||
|
|
||||||
|
def query(self, from_release, to_release):
|
||||||
|
super().query(from_release, to_release)
|
||||||
|
for deploy in self.data.get("deploy", []):
|
||||||
|
if deploy.get("from_release") == from_release and deploy.get("to_release") == to_release:
|
||||||
|
return deploy
|
||||||
|
return None
|
||||||
|
|
||||||
|
def query_all(self):
|
||||||
|
return self.data.get("deploy", [])
|
||||||
|
|
||||||
|
def update(self, from_release, to_release, reboot_required, state):
|
||||||
|
super().update(from_release, to_release, reboot_required, state)
|
||||||
|
deploy = self.query(from_release, to_release)
|
||||||
|
if not deploy:
|
||||||
|
raise DeployDoNotExist("Error to update. Deploy do not exist.")
|
||||||
|
deploy_data = {
|
||||||
|
"deploy": []
|
||||||
|
}
|
||||||
|
deploy_data["deploy"].append({
|
||||||
|
"from_release": from_release,
|
||||||
|
"to_release": to_release,
|
||||||
|
"reboot_required": reboot_required,
|
||||||
|
"state": state
|
||||||
|
})
|
||||||
|
self.data.update(deploy_data)
|
||||||
|
save_to_json_file(constants.SOFTWARE_JSON_FILE, self.data)
|
||||||
|
|
||||||
|
def delete(self, from_release, to_release):
|
||||||
|
super().delete(from_release, to_release)
|
||||||
|
deploy = self.query(from_release, to_release)
|
||||||
|
if not deploy:
|
||||||
|
raise DeployDoNotExist("Error to delete. Deploy do not exist.")
|
||||||
|
self.data.get("deploy").remove(deploy)
|
||||||
|
save_to_json_file(constants.SOFTWARE_JSON_FILE, self.data)
|
||||||
|
|
||||||
|
|
||||||
|
class DeployHostHandler(DeployHosts):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.data = get_software_filesystem_data()
|
||||||
|
|
||||||
|
def create(self, hostname, software_release, target_release, state=None):
|
||||||
|
super().create(hostname, software_release, target_release, state)
|
||||||
|
deploy = self.query(hostname, software_release, target_release)
|
||||||
|
if deploy:
|
||||||
|
raise DeployAlreadyExist("Error to create. Deploy host already exist.")
|
||||||
|
|
||||||
|
new_deploy_host = {
|
||||||
|
"hostname": hostname,
|
||||||
|
"software_release": software_release,
|
||||||
|
"target_release": target_release,
|
||||||
|
"state": state
|
||||||
|
}
|
||||||
|
|
||||||
|
deploy_data = self.data.get("deploy_host", [])
|
||||||
|
if not deploy_data:
|
||||||
|
deploy_data = {
|
||||||
|
"deploy_host": []
|
||||||
|
}
|
||||||
|
deploy_data["deploy_host"].append(new_deploy_host)
|
||||||
|
self.data.update(deploy_data)
|
||||||
|
else:
|
||||||
|
deploy_data.append(new_deploy_host)
|
||||||
|
save_to_json_file(constants.SOFTWARE_JSON_FILE, self.data)
|
||||||
|
|
||||||
|
def query(self, hostname, software_release, target_release):
|
||||||
|
super().query(hostname, software_release, target_release)
|
||||||
|
for deploy in self.data.get("deploy_host", []):
|
||||||
|
if (deploy.get("hostname") == hostname and deploy.get("software_release") == software_release
|
||||||
|
and deploy.get("target_release") == target_release):
|
||||||
|
return deploy
|
||||||
|
return None
|
||||||
|
|
||||||
|
def query_by_hostname(self, hostname):
|
||||||
|
super().query_by_hostname(hostname)
|
||||||
|
for deploy in self.data.get("deploy_host", []):
|
||||||
|
if deploy.get("hostname") == hostname:
|
||||||
|
return deploy
|
||||||
|
return None
|
||||||
|
|
||||||
|
def query_all(self):
|
||||||
|
return self.data.get("deploy_host", [])
|
||||||
|
|
||||||
|
def update(self, hostname, software_release, target_release, state):
|
||||||
|
super().update(hostname, software_release, target_release, state)
|
||||||
|
deploy = self.query(hostname, software_release, target_release)
|
||||||
|
if not deploy:
|
||||||
|
raise Exception("Error to update. Deploy host do not exist.")
|
||||||
|
|
||||||
|
index = self.data.get("deploy_host", []).index(deploy)
|
||||||
|
self.data["deploy_host"][index].update({
|
||||||
|
"hostname": hostname,
|
||||||
|
"software_release": software_release,
|
||||||
|
"target_release": target_release,
|
||||||
|
"state": state
|
||||||
|
})
|
||||||
|
save_to_json_file(constants.SOFTWARE_JSON_FILE, self.data)
|
||||||
|
|
||||||
|
def delete_all(self):
|
||||||
|
self.data.get("deploy_host").clear()
|
||||||
|
save_to_json_file(constants.SOFTWARE_JSON_FILE, self.data)
|
||||||
|
|
||||||
|
def delete_by_hostname(self, hostname):
|
||||||
|
super().delete_by_hostname(hostname)
|
||||||
|
deploy = self.query_by_hostname(hostname)
|
||||||
|
if not deploy:
|
||||||
|
raise DeployDoNotExist("Error to delete. Deploy host do not exist.")
|
||||||
|
self.data.get("deploy_host").remove(deploy)
|
||||||
|
save_to_json_file(constants.SOFTWARE_JSON_FILE, self.data)
|
||||||
|
|
||||||
|
def delete(self, hostname, software_release, target_release):
|
||||||
|
super().delete(hostname, software_release, target_release)
|
||||||
|
deploy = self.query(hostname, software_release, target_release)
|
||||||
|
if not deploy:
|
||||||
|
raise DeployDoNotExist("Error to delete. Deploy host do not exist.")
|
||||||
|
self.data.get("deploy_host").remove(deploy)
|
||||||
|
save_to_json_file(constants.SOFTWARE_JSON_FILE, self.data)
|
||||||
|
@@ -269,6 +269,10 @@ def load_from_json_file(file):
|
|||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
LOG.error("File %s not found", file)
|
LOG.error("File %s not found", file)
|
||||||
return None
|
return None
|
||||||
|
# Avoid error to read an empty file
|
||||||
|
except ValueError:
|
||||||
|
return {}
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.error("Problem reading from %s: %s", file, e)
|
LOG.error("Problem reading from %s: %s", file, e)
|
||||||
return None
|
return None
|
||||||
@@ -289,6 +293,13 @@ def check_state(state, states):
|
|||||||
def check_instances(params: list, instance):
|
def check_instances(params: list, instance):
|
||||||
for p in params:
|
for p in params:
|
||||||
if not isinstance(p, instance):
|
if not isinstance(p, instance):
|
||||||
msg = "Param %s must be type: %s" % (p, instance)
|
msg = "Param with value %s must be type: %s" % (p, instance)
|
||||||
LOG.exception(msg)
|
LOG.exception(msg)
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
|
|
||||||
|
def get_software_filesystem_data():
|
||||||
|
if os.path.exists(constants.SOFTWARE_JSON_FILE):
|
||||||
|
data = load_from_json_file(constants.SOFTWARE_JSON_FILE)
|
||||||
|
else:
|
||||||
|
data = {}
|
||||||
|
return data
|
||||||
|
Reference in New Issue
Block a user