Merge "Catchup YAPF formatting"
This commit is contained in:
commit
43efbb0c63
|
@ -404,12 +404,12 @@
|
||||||
# Timeout in minutes for deploying a node (integer value)
|
# Timeout in minutes for deploying a node (integer value)
|
||||||
#deploy_node = 45
|
#deploy_node = 45
|
||||||
|
|
||||||
# Timeout in minutes for relabeling a node (integer value)
|
|
||||||
#relabel_node = 5
|
|
||||||
|
|
||||||
# Timeout in minutes between deployment completion and the all boot actions
|
# Timeout in minutes between deployment completion and the all boot actions
|
||||||
# reporting status (integer value)
|
# reporting status (integer value)
|
||||||
#bootaction_final_status = 15
|
#bootaction_final_status = 15
|
||||||
|
|
||||||
# Timeout in minutes for releasing a node (integer value)
|
# Timeout in minutes for releasing a node (integer value)
|
||||||
#destroy_node = 30
|
#destroy_node = 30
|
||||||
|
|
||||||
|
# Timeout in minutes for relabeling a node (integer value)
|
||||||
|
#relabel_node = 5
|
||||||
|
|
|
@ -276,6 +276,9 @@
|
||||||
# Logger name for Node driver logging (string value)
|
# Logger name for Node driver logging (string value)
|
||||||
#nodedriver_logger_name = ${global_logger_name}.nodedriver
|
#nodedriver_logger_name = ${global_logger_name}.nodedriver
|
||||||
|
|
||||||
|
# Logger name for Kubernetes driver logging (string value)
|
||||||
|
#kubernetesdriver_logger_name = ${global_logger_name}.kubernetesdriver
|
||||||
|
|
||||||
# Logger name for API server logging (string value)
|
# Logger name for API server logging (string value)
|
||||||
#control_logger_name = ${global_logger_name}.control
|
#control_logger_name = ${global_logger_name}.control
|
||||||
|
|
||||||
|
@ -350,6 +353,9 @@
|
||||||
# Module path string of the Node driver to enable (string value)
|
# Module path string of the Node driver to enable (string value)
|
||||||
#node_driver = drydock_provisioner.drivers.node.maasdriver.driver.MaasNodeDriver
|
#node_driver = drydock_provisioner.drivers.node.maasdriver.driver.MaasNodeDriver
|
||||||
|
|
||||||
|
# Module path string of the Kubernetes driver to enable (string value)
|
||||||
|
#kubernetes_driver = drydock_provisioner.drivers.kubernetes.promenade_driver.driver.PromenadeDriver
|
||||||
|
|
||||||
# Module path string of the Network driver enable (string value)
|
# Module path string of the Network driver enable (string value)
|
||||||
#network_driver = <None>
|
#network_driver = <None>
|
||||||
|
|
||||||
|
@ -404,3 +410,6 @@
|
||||||
|
|
||||||
# Timeout in minutes for releasing a node (integer value)
|
# Timeout in minutes for releasing a node (integer value)
|
||||||
#destroy_node = 30
|
#destroy_node = 30
|
||||||
|
|
||||||
|
# Timeout in minutes for relabeling a node (integer value)
|
||||||
|
#relabel_node = 5
|
||||||
|
|
|
@ -38,6 +38,10 @@
|
||||||
# POST /api/v1.0/tasks
|
# POST /api/v1.0/tasks
|
||||||
#"physical_provisioner:destroy_nodes": "role:admin"
|
#"physical_provisioner:destroy_nodes": "role:admin"
|
||||||
|
|
||||||
|
# Create relabel_nodes task
|
||||||
|
# POST /api/v1.0/tasks
|
||||||
|
#"physical_provisioner:relabel_nodes": "role:admin"
|
||||||
|
|
||||||
# Read build data for a node
|
# Read build data for a node
|
||||||
# GET /api/v1.0/nodes/{nodename}/builddata
|
# GET /api/v1.0/nodes/{nodename}/builddata
|
||||||
#"physical_provisioner:read_build_data": "role:admin"
|
#"physical_provisioner:read_build_data": "role:admin"
|
||||||
|
|
|
@ -64,8 +64,8 @@ def part_list(ctx):
|
||||||
"""List parts of a design."""
|
"""List parts of a design."""
|
||||||
click.echo(
|
click.echo(
|
||||||
json.dumps(
|
json.dumps(
|
||||||
PartList(ctx.obj['CLIENT'], design_id=ctx.obj['DESIGN_ID'])
|
PartList(ctx.obj['CLIENT'],
|
||||||
.invoke()))
|
design_id=ctx.obj['DESIGN_ID']).invoke()))
|
||||||
|
|
||||||
|
|
||||||
@part.command(name='show')
|
@part.command(name='show')
|
||||||
|
|
|
@ -79,8 +79,8 @@ def task_create(ctx,
|
||||||
if node_names else [],
|
if node_names else [],
|
||||||
rack_names=[x.strip() for x in rack_names.split(',')]
|
rack_names=[x.strip() for x in rack_names.split(',')]
|
||||||
if rack_names else [],
|
if rack_names else [],
|
||||||
node_tags=[x.strip() for x in node_tags.split(',')]
|
node_tags=[x.strip()
|
||||||
if node_tags else [],
|
for x in node_tags.split(',')] if node_tags else [],
|
||||||
block=block,
|
block=block,
|
||||||
poll_interval=poll_interval).invoke()))
|
poll_interval=poll_interval).invoke()))
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,8 @@ class RelabelNode(PromenadeAction):
|
||||||
for n in nodes:
|
for n in nodes:
|
||||||
# Relabel node through Promenade
|
# Relabel node through Promenade
|
||||||
try:
|
try:
|
||||||
self.logger.info("Relabeling node %s with node label data." % n.name)
|
self.logger.info(
|
||||||
|
"Relabeling node %s with node label data." % n.name)
|
||||||
|
|
||||||
labels_dict = n.get_node_labels()
|
labels_dict = n.get_node_labels()
|
||||||
msg = "Set labels %s for node %s" % (str(labels_dict), n.name)
|
msg = "Set labels %s for node %s" % (str(labels_dict), n.name)
|
||||||
|
|
|
@ -35,8 +35,7 @@ class PromenadeDriver(KubernetesDriver):
|
||||||
driver_desc = 'Promenade Kubernetes Driver'
|
driver_desc = 'Promenade Kubernetes Driver'
|
||||||
|
|
||||||
action_class_map = {
|
action_class_map = {
|
||||||
hd_fields.OrchestratorAction.RelabelNode:
|
hd_fields.OrchestratorAction.RelabelNode: RelabelNode,
|
||||||
RelabelNode,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
|
@ -103,8 +102,7 @@ class PromenadeDriver(KubernetesDriver):
|
||||||
action.start)
|
action.start)
|
||||||
|
|
||||||
timeout = action_timeouts.get(
|
timeout = action_timeouts.get(
|
||||||
task.action,
|
task.action, config.config_mgr.conf.timeouts.relabel_node)
|
||||||
config.config_mgr.conf.timeouts.relabel_node)
|
|
||||||
finished, running = concurrent.futures.wait(
|
finished, running = concurrent.futures.wait(
|
||||||
subtask_futures.values(), timeout=(timeout * 60))
|
subtask_futures.values(), timeout=(timeout * 60))
|
||||||
|
|
||||||
|
@ -118,8 +116,8 @@ class PromenadeDriver(KubernetesDriver):
|
||||||
task.failure()
|
task.failure()
|
||||||
else:
|
else:
|
||||||
if f.exception():
|
if f.exception():
|
||||||
msg = ("Subtask %s raised unexpected exception: %s"
|
msg = ("Subtask %s raised unexpected exception: %s" %
|
||||||
% (str(uuid.UUID(bytes=t)), str(f.exception())))
|
(str(uuid.UUID(bytes=t)), str(f.exception())))
|
||||||
self.logger.error(msg, exc_info=f.exception())
|
self.logger.error(msg, exc_info=f.exception())
|
||||||
task.add_status_msg(
|
task.add_status_msg(
|
||||||
msg=msg,
|
msg=msg,
|
||||||
|
|
|
@ -22,6 +22,7 @@ from keystoneauth1 import exceptions as exc
|
||||||
import drydock_provisioner.error as errors
|
import drydock_provisioner.error as errors
|
||||||
from drydock_provisioner.util import KeystoneUtils
|
from drydock_provisioner.util import KeystoneUtils
|
||||||
|
|
||||||
|
|
||||||
# TODO: Remove this local implementation of Promenade Session and client once
|
# TODO: Remove this local implementation of Promenade Session and client once
|
||||||
# Promenade api client is available as part of Promenade project.
|
# Promenade api client is available as part of Promenade project.
|
||||||
class PromenadeSession(object):
|
class PromenadeSession(object):
|
||||||
|
@ -35,10 +36,7 @@ class PromenadeSession(object):
|
||||||
read timeout to use
|
read timeout to use
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self, scheme='http', marker=None, timeout=None):
|
||||||
scheme='http',
|
|
||||||
marker=None,
|
|
||||||
timeout=None):
|
|
||||||
self.logger = logging.getLogger(__name__)
|
self.logger = logging.getLogger(__name__)
|
||||||
self.__session = requests.Session()
|
self.__session = requests.Session()
|
||||||
|
|
||||||
|
@ -63,8 +61,8 @@ class PromenadeSession(object):
|
||||||
|
|
||||||
def set_auth(self):
|
def set_auth(self):
|
||||||
|
|
||||||
auth_header = self._auth_gen()
|
auth_header = self._auth_gen()
|
||||||
self.__session.headers.update(auth_header)
|
self.__session.headers.update(auth_header)
|
||||||
|
|
||||||
def get(self, route, query=None, timeout=None):
|
def get(self, route, query=None, timeout=None):
|
||||||
"""
|
"""
|
||||||
|
@ -220,11 +218,10 @@ class PromenadeSession(object):
|
||||||
try:
|
try:
|
||||||
ks_session = KeystoneUtils.get_session()
|
ks_session = KeystoneUtils.get_session()
|
||||||
except exc.AuthorizationFailure as aferr:
|
except exc.AuthorizationFailure as aferr:
|
||||||
self.logger.error(
|
self.logger.error('Could not authorize against Keystone: %s',
|
||||||
'Could not authorize against Keystone: %s',
|
str(aferr))
|
||||||
str(aferr))
|
raise errors.DriverError(
|
||||||
raise errors.DriverError('Could not authorize against Keystone: %s',
|
'Could not authorize against Keystone: %s', str(aferr))
|
||||||
str(aferr))
|
|
||||||
|
|
||||||
return ks_session
|
return ks_session
|
||||||
|
|
||||||
|
@ -235,8 +232,7 @@ class PromenadeSession(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
prom_endpoint = ks_session.get_endpoint(
|
prom_endpoint = ks_session.get_endpoint(
|
||||||
interface='internal',
|
interface='internal', service_type='kubernetesprovisioner')
|
||||||
service_type='kubernetesprovisioner')
|
|
||||||
except exc.EndpointNotFound:
|
except exc.EndpointNotFound:
|
||||||
self.logger.error("Could not find an internal interface"
|
self.logger.error("Could not find an internal interface"
|
||||||
" defined in Keystone for Promenade")
|
" defined in Keystone for Promenade")
|
||||||
|
|
|
@ -278,7 +278,8 @@ class DestroyNode(BaseMaasAction):
|
||||||
site_design)
|
site_design)
|
||||||
for n in nodes:
|
for n in nodes:
|
||||||
try:
|
try:
|
||||||
machine = machine_list.identify_baremetal_node(n, update_name=False)
|
machine = machine_list.identify_baremetal_node(
|
||||||
|
n, update_name=False)
|
||||||
|
|
||||||
if machine is None:
|
if machine is None:
|
||||||
msg = "Could not locate machine for node {}".format(n.name)
|
msg = "Could not locate machine for node {}".format(n.name)
|
||||||
|
@ -297,7 +298,8 @@ class DestroyNode(BaseMaasAction):
|
||||||
try:
|
try:
|
||||||
machine.release(erase_disk=True, quick_erase=True)
|
machine.release(erase_disk=True, quick_erase=True)
|
||||||
except errors.DriverError:
|
except errors.DriverError:
|
||||||
msg = "Error Releasing node {}, skipping".format(n.name)
|
msg = "Error Releasing node {}, skipping".format(
|
||||||
|
n.name)
|
||||||
self.logger.warning(msg)
|
self.logger.warning(msg)
|
||||||
self.task.add_status_msg(
|
self.task.add_status_msg(
|
||||||
msg=msg, error=True, ctx=n.name, ctx_type='node')
|
msg=msg, error=True, ctx=n.name, ctx_type='node')
|
||||||
|
@ -306,25 +308,26 @@ class DestroyNode(BaseMaasAction):
|
||||||
|
|
||||||
# node release with erase disk will take sometime monitor it
|
# node release with erase disk will take sometime monitor it
|
||||||
attempts = 0
|
attempts = 0
|
||||||
max_attempts = (config.config_mgr.conf.timeouts.destroy_node
|
max_attempts = (
|
||||||
* 60) // config.config_mgr.conf.maasdriver.poll_interval
|
config.config_mgr.conf.timeouts.destroy_node *
|
||||||
|
60) // config.config_mgr.conf.maasdriver.poll_interval
|
||||||
|
|
||||||
while (attempts < max_attempts
|
while (attempts < max_attempts and
|
||||||
and (not machine.status_name.startswith('Ready')
|
(not machine.status_name.startswith('Ready')
|
||||||
and not machine.status_name.startswith(
|
and not machine.status_name.startswith('Failed'))):
|
||||||
'Failed'))):
|
|
||||||
attempts = attempts + 1
|
attempts = attempts + 1
|
||||||
time.sleep(
|
time.sleep(
|
||||||
config.config_mgr.conf.maasdriver.poll_interval)
|
config.config_mgr.conf.maasdriver.poll_interval)
|
||||||
try:
|
try:
|
||||||
machine.refresh()
|
machine.refresh()
|
||||||
self.logger.debug(
|
self.logger.debug(
|
||||||
"Polling node {} status attempt {:d} of {:d}: {}".format(
|
"Polling node {} status attempt {:d} of {:d}: {}"
|
||||||
n.name, attempts, max_attempts,
|
.format(n.name, attempts, max_attempts,
|
||||||
machine.status_name))
|
machine.status_name))
|
||||||
except Exception:
|
except Exception:
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
"Error updating node {} status during release node, will re-attempt.".format(n.name))
|
"Error updating node {} status during release node, will re-attempt."
|
||||||
|
.format(n.name))
|
||||||
if machine.status_name.startswith('Ready'):
|
if machine.status_name.startswith('Ready'):
|
||||||
msg = "Node {} released and disk erased.".format(
|
msg = "Node {} released and disk erased.".format(
|
||||||
n.name)
|
n.name)
|
||||||
|
@ -354,8 +357,8 @@ class DestroyNode(BaseMaasAction):
|
||||||
try:
|
try:
|
||||||
if n.oob_type == 'libvirt':
|
if n.oob_type == 'libvirt':
|
||||||
self.logger.info(
|
self.logger.info(
|
||||||
'Resetting MaaS virsh power parameters for node {}.'.format(
|
'Resetting MaaS virsh power parameters for node {}.'
|
||||||
n.name))
|
.format(n.name))
|
||||||
# setting power type attibutes to empty string
|
# setting power type attibutes to empty string
|
||||||
# will remove them from maas BMC table
|
# will remove them from maas BMC table
|
||||||
machine.reset_power_parameters()
|
machine.reset_power_parameters()
|
||||||
|
@ -363,8 +366,8 @@ class DestroyNode(BaseMaasAction):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
machine.delete()
|
machine.delete()
|
||||||
msg = "Deleted Node: {} in status: {}.".format(n.name,
|
msg = "Deleted Node: {} in status: {}.".format(
|
||||||
machine.status_name)
|
n.name, machine.status_name)
|
||||||
self.logger.info(msg)
|
self.logger.info(msg)
|
||||||
self.task.add_status_msg(
|
self.task.add_status_msg(
|
||||||
msg=msg, error=False, ctx=n.name, ctx_type='node')
|
msg=msg, error=False, ctx=n.name, ctx_type='node')
|
||||||
|
@ -1147,16 +1150,17 @@ class ConfigureHardware(BaseMaasAction):
|
||||||
|
|
||||||
# Poll machine status
|
# Poll machine status
|
||||||
attempts = 0
|
attempts = 0
|
||||||
max_attempts = (config.config_mgr.conf.timeouts.configure_hardware
|
max_attempts = (
|
||||||
* 60) // config.config_mgr.conf.maasdriver.poll_interval
|
config.config_mgr.conf.timeouts.configure_hardware
|
||||||
|
* 60
|
||||||
|
) // config.config_mgr.conf.maasdriver.poll_interval
|
||||||
|
|
||||||
while (attempts < max_attempts and
|
while (attempts < max_attempts and
|
||||||
(machine.status_name != 'Ready' and
|
(machine.status_name != 'Ready' and
|
||||||
not machine.status_name.startswith('Failed'))):
|
not machine.status_name.startswith('Failed'))):
|
||||||
attempts = attempts + 1
|
attempts = attempts + 1
|
||||||
time.sleep(
|
time.sleep(config.config_mgr.conf.maasdriver.
|
||||||
config.config_mgr.conf.maasdriver.poll_interval
|
poll_interval)
|
||||||
)
|
|
||||||
try:
|
try:
|
||||||
machine.refresh()
|
machine.refresh()
|
||||||
self.logger.debug(
|
self.logger.debug(
|
||||||
|
@ -1226,7 +1230,9 @@ class ConfigureHardware(BaseMaasAction):
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
msg = "Error commissioning node %s: %s" % (n.name, str(ex))
|
msg = "Error commissioning node %s: %s" % (n.name, str(ex))
|
||||||
self.logger.warning(msg)
|
self.logger.warning(msg)
|
||||||
self.logger.debug("Unhandled exception attempting to commission node.", exc_info=ex)
|
self.logger.debug(
|
||||||
|
"Unhandled exception attempting to commission node.",
|
||||||
|
exc_info=ex)
|
||||||
self.task.add_status_msg(
|
self.task.add_status_msg(
|
||||||
msg=msg, error=True, ctx=n.name, ctx_type='node')
|
msg=msg, error=True, ctx=n.name, ctx_type='node')
|
||||||
self.task.failure(focus=n.get_id())
|
self.task.failure(focus=n.get_id())
|
||||||
|
@ -2312,8 +2318,9 @@ class DeployNode(BaseMaasAction):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
attempts = 0
|
attempts = 0
|
||||||
max_attempts = (config.config_mgr.conf.timeouts.deploy_node
|
max_attempts = (
|
||||||
* 60) // config.config_mgr.conf.maasdriver.poll_interval
|
config.config_mgr.conf.timeouts.deploy_node *
|
||||||
|
60) // config.config_mgr.conf.maasdriver.poll_interval
|
||||||
|
|
||||||
while (attempts < max_attempts
|
while (attempts < max_attempts
|
||||||
and (not machine.status_name.startswith('Deployed')
|
and (not machine.status_name.startswith('Deployed')
|
||||||
|
|
|
@ -423,8 +423,8 @@ class Machine(model_base.ResourceBase):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
raise errors.DriverError(
|
raise errors.DriverError(
|
||||||
"Failed updating power parameters MAAS url {} - return code {}\n{}".format(
|
"Failed updating power parameters MAAS url {} - return code {}\n{}"
|
||||||
url, resp.status_code.resp.text))
|
.format(url, resp.status_code.resp.text))
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
"""Serialize this resource instance into a dict.
|
"""Serialize this resource instance into a dict.
|
||||||
|
|
|
@ -87,7 +87,8 @@ class BootAction(base.DrydockPersistentObject, base.DrydockObject):
|
||||||
for a in self.asset_list:
|
for a in self.asset_list:
|
||||||
if type_filter is None or (type_filter is not None
|
if type_filter is None or (type_filter is not None
|
||||||
and a.type == type_filter):
|
and a.type == type_filter):
|
||||||
a.render(nodename, site_design, action_id, action_key, design_ref)
|
a.render(nodename, site_design, action_id, action_key,
|
||||||
|
design_ref)
|
||||||
assets.append(a)
|
assets.append(a)
|
||||||
|
|
||||||
return assets
|
return assets
|
||||||
|
|
|
@ -70,12 +70,12 @@ class OrchestratorAction(BaseDrydockEnum):
|
||||||
|
|
||||||
ALL = (Noop, ValidateDesign, VerifySite, PrepareSite, VerifyNodes,
|
ALL = (Noop, ValidateDesign, VerifySite, PrepareSite, VerifyNodes,
|
||||||
PrepareNodes, DeployNodes, BootactionReport, DestroyNodes,
|
PrepareNodes, DeployNodes, BootactionReport, DestroyNodes,
|
||||||
RelabelNodes, ConfigNodePxe, SetNodeBoot, PowerOffNode,
|
RelabelNodes, ConfigNodePxe, SetNodeBoot, PowerOffNode, PowerOnNode,
|
||||||
PowerOnNode, PowerCycleNode, InterrogateOob, RelabelNode,
|
PowerCycleNode, InterrogateOob, RelabelNode, CreateNetworkTemplate,
|
||||||
CreateNetworkTemplate, CreateStorageTemplate, CreateBootMedia,
|
CreateStorageTemplate, CreateBootMedia, PrepareHardwareConfig,
|
||||||
PrepareHardwareConfig, ConfigureHardware, InterrogateNode,
|
ConfigureHardware, InterrogateNode, ApplyNodeNetworking,
|
||||||
ApplyNodeNetworking, ApplyNodeStorage, ApplyNodePlatform,
|
ApplyNodeStorage, ApplyNodePlatform, DeployNode, DestroyNode,
|
||||||
DeployNode, DestroyNode, ConfigureNodeProvisioner)
|
ConfigureNodeProvisioner)
|
||||||
|
|
||||||
|
|
||||||
class OrchestratorActionField(fields.BaseEnumField):
|
class OrchestratorActionField(fields.BaseEnumField):
|
||||||
|
|
|
@ -338,6 +338,7 @@ class BaremetalNode(drydock_provisioner.objects.hostprofile.HostProfile):
|
||||||
|
|
||||||
return labels_dict
|
return labels_dict
|
||||||
|
|
||||||
|
|
||||||
@base.DrydockObjectRegistry.register
|
@base.DrydockObjectRegistry.register
|
||||||
class BaremetalNodeList(base.DrydockObjectListBase, base.DrydockObject):
|
class BaremetalNodeList(base.DrydockObjectListBase, base.DrydockObject):
|
||||||
|
|
||||||
|
|
|
@ -274,7 +274,8 @@ class Task(object):
|
||||||
"Bubbling subtask success for entity %s." % se)
|
"Bubbling subtask success for entity %s." % se)
|
||||||
self.result.add_success(se)
|
self.result.add_success(se)
|
||||||
else:
|
else:
|
||||||
self.logger.debug("Skipping subtask success due to action filter.")
|
self.logger.debug(
|
||||||
|
"Skipping subtask success due to action filter.")
|
||||||
# All failures are bubbled up.
|
# All failures are bubbled up.
|
||||||
if self.retry == 0 or (self.retry == st.retry):
|
if self.retry == 0 or (self.retry == st.retry):
|
||||||
for fe in st.result.failures:
|
for fe in st.result.failures:
|
||||||
|
@ -283,8 +284,7 @@ class Task(object):
|
||||||
self.result.add_failure(fe)
|
self.result.add_failure(fe)
|
||||||
else:
|
else:
|
||||||
self.logger.debug(
|
self.logger.debug(
|
||||||
"Skipping failures as they mismatch task retry sequence."
|
"Skipping failures as they mismatch task retry sequence.")
|
||||||
)
|
|
||||||
|
|
||||||
def align_result(self, action_filter=None, reset_status=True):
|
def align_result(self, action_filter=None, reset_status=True):
|
||||||
"""Align the result of this task with the combined results of all the subtasks.
|
"""Align the result of this task with the combined results of all the subtasks.
|
||||||
|
|
|
@ -245,9 +245,8 @@ class DestroyNodes(BaseAction):
|
||||||
node_filter=self.task.node_filter)
|
node_filter=self.task.node_filter)
|
||||||
self.task.register_subtask(node_release_task)
|
self.task.register_subtask(node_release_task)
|
||||||
|
|
||||||
self.logger.info(
|
self.logger.info("Starting node driver task %s to Release nodes." %
|
||||||
"Starting node driver task %s to Release nodes." %
|
(node_release_task.get_id()))
|
||||||
(node_release_task.get_id()))
|
|
||||||
node_driver.execute_task(node_release_task.get_id())
|
node_driver.execute_task(node_release_task.get_id())
|
||||||
|
|
||||||
node_release_task = self.state_manager.get_task(
|
node_release_task = self.state_manager.get_task(
|
||||||
|
@ -1079,9 +1078,8 @@ class RelabelNodes(BaseAction):
|
||||||
node_filter=nf)
|
node_filter=nf)
|
||||||
self.task.register_subtask(relabel_node_task)
|
self.task.register_subtask(relabel_node_task)
|
||||||
|
|
||||||
self.logger.info(
|
self.logger.info("Starting kubernetes driver task %s to relabel nodes."
|
||||||
"Starting kubernetes driver task %s to relabel nodes." %
|
% (relabel_node_task.get_id()))
|
||||||
(relabel_node_task.get_id()))
|
|
||||||
kubernetes_driver.execute_task(relabel_node_task.get_id())
|
kubernetes_driver.execute_task(relabel_node_task.get_id())
|
||||||
|
|
||||||
relabel_node_task = self.state_manager.get_task(
|
relabel_node_task = self.state_manager.get_task(
|
||||||
|
|
|
@ -109,8 +109,9 @@ class Orchestrator(object):
|
||||||
kubernetes_driver_class = getattr(
|
kubernetes_driver_class = getattr(
|
||||||
importlib.import_module(m), c, None)
|
importlib.import_module(m), c, None)
|
||||||
if kubernetes_driver_class is not None:
|
if kubernetes_driver_class is not None:
|
||||||
self.enabled_drivers['kubernetes'] = kubernetes_driver_class(
|
self.enabled_drivers[
|
||||||
state_manager=state_manager, orchestrator=self)
|
'kubernetes'] = kubernetes_driver_class(
|
||||||
|
state_manager=state_manager, orchestrator=self)
|
||||||
|
|
||||||
def watch_for_tasks(self):
|
def watch_for_tasks(self):
|
||||||
"""Start polling the database watching for Queued tasks to execute."""
|
"""Start polling the database watching for Queued tasks to execute."""
|
||||||
|
|
|
@ -40,17 +40,15 @@ class NetworkTrunkingRational(Validators):
|
||||||
)
|
)
|
||||||
|
|
||||||
# trunking mode is disabled, default_network must be defined
|
# trunking mode is disabled, default_network must be defined
|
||||||
if (network_link.trunk_mode ==
|
if (network_link.trunk_mode == hd_fields.NetworkLinkTrunkingMode.
|
||||||
hd_fields.NetworkLinkTrunkingMode.Disabled
|
Disabled and network_link.native_network is None):
|
||||||
and network_link.native_network is None):
|
|
||||||
|
|
||||||
msg = 'Trunking mode is disabled, a trunking default_network must be defined'
|
msg = 'Trunking mode is disabled, a trunking default_network must be defined'
|
||||||
self.report_error(
|
self.report_error(
|
||||||
msg, [network_link.doc_ref],
|
msg, [network_link.doc_ref],
|
||||||
"Non-trunked links must have a native network defined.")
|
"Non-trunked links must have a native network defined.")
|
||||||
elif (network_link.trunk_mode ==
|
elif (network_link.trunk_mode == hd_fields.NetworkLinkTrunkingMode.
|
||||||
hd_fields.NetworkLinkTrunkingMode.Disabled
|
Disabled and network_link.native_network is not None):
|
||||||
and network_link.native_network is not None):
|
|
||||||
network = site_design.get_network(network_link.native_network)
|
network = site_design.get_network(network_link.native_network)
|
||||||
if network and network.vlan_id:
|
if network and network.vlan_id:
|
||||||
msg = "Network link native network has a defined VLAN tag."
|
msg = "Network link native network has a defined VLAN tag."
|
||||||
|
|
|
@ -38,15 +38,15 @@ class DrydockPolicy(object):
|
||||||
|
|
||||||
# Orchestrator Policy
|
# Orchestrator Policy
|
||||||
task_rules = [
|
task_rules = [
|
||||||
policy.DocumentedRuleDefault('physical_provisioner:read_task',
|
policy.DocumentedRuleDefault(
|
||||||
'role:admin', 'Get task status',
|
'physical_provisioner:read_task', 'role:admin', 'Get task status',
|
||||||
[{
|
[{
|
||||||
'path': '/api/v1.0/tasks',
|
'path': '/api/v1.0/tasks',
|
||||||
'method': 'GET'
|
'method': 'GET'
|
||||||
}, {
|
}, {
|
||||||
'path': '/api/v1.0/tasks/{task_id}',
|
'path': '/api/v1.0/tasks/{task_id}',
|
||||||
'method': 'GET'
|
'method': 'GET'
|
||||||
}]),
|
}]),
|
||||||
policy.DocumentedRuleDefault('physical_provisioner:create_task',
|
policy.DocumentedRuleDefault('physical_provisioner:create_task',
|
||||||
'role:admin', 'Create a task',
|
'role:admin', 'Create a task',
|
||||||
[{
|
[{
|
||||||
|
@ -103,10 +103,11 @@ class DrydockPolicy(object):
|
||||||
}]),
|
}]),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
'physical_provisioner:read_build_data', 'role:admin',
|
'physical_provisioner:read_build_data', 'role:admin',
|
||||||
'Read build data for a node',
|
'Read build data for a node', [{
|
||||||
[{
|
'path':
|
||||||
'path': '/api/v1.0/nodes/{nodename}/builddata',
|
'/api/v1.0/nodes/{nodename}/builddata',
|
||||||
'method': 'GET',
|
'method':
|
||||||
|
'GET',
|
||||||
}]),
|
}]),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -169,9 +169,8 @@ class DrydockState(object):
|
||||||
with self.db_engine.connect() as conn:
|
with self.db_engine.connect() as conn:
|
||||||
if allowed_actions is None:
|
if allowed_actions is None:
|
||||||
query = self.tasks_tbl.select().where(
|
query = self.tasks_tbl.select().where(
|
||||||
self.tasks_tbl.c.status ==
|
self.tasks_tbl.c.status == hd_fields.TaskStatus.
|
||||||
hd_fields.TaskStatus.Queued).order_by(
|
Queued).order_by(self.tasks_tbl.c.created.asc())
|
||||||
self.tasks_tbl.c.created.asc())
|
|
||||||
rs = conn.execute(query)
|
rs = conn.execute(query)
|
||||||
else:
|
else:
|
||||||
query = sql.text("SELECT * FROM tasks WHERE "
|
query = sql.text("SELECT * FROM tasks WHERE "
|
||||||
|
@ -340,8 +339,8 @@ class DrydockState(object):
|
||||||
try:
|
try:
|
||||||
with self.db_engine.connect() as conn:
|
with self.db_engine.connect() as conn:
|
||||||
query = self.active_instance_tbl.update().where(
|
query = self.active_instance_tbl.update().where(
|
||||||
self.active_instance_tbl.c.identity ==
|
self.active_instance_tbl.c.identity == leader_id.
|
||||||
leader_id.bytes).values(last_ping=datetime.utcnow())
|
bytes).values(last_ping=datetime.utcnow())
|
||||||
rs = conn.execute(query)
|
rs = conn.execute(query)
|
||||||
rc = rs.rowcount
|
rc = rs.rowcount
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,8 @@ from drydock_provisioner.control.api import start_api
|
||||||
class TestClass(object):
|
class TestClass(object):
|
||||||
def test_bootaction_context(self, falcontest, seed_bootaction):
|
def test_bootaction_context(self, falcontest, seed_bootaction):
|
||||||
"""Test that the API will return a boot action context"""
|
"""Test that the API will return a boot action context"""
|
||||||
url = "/api/v1.0/bootactions/nodes/%s/units" % seed_bootaction['nodename']
|
url = "/api/v1.0/bootactions/nodes/%s/units" % seed_bootaction[
|
||||||
|
'nodename']
|
||||||
auth_hdr = {'X-Bootaction-Key': "%s" % seed_bootaction['identity_key']}
|
auth_hdr = {'X-Bootaction-Key': "%s" % seed_bootaction['identity_key']}
|
||||||
|
|
||||||
result = falcontest.simulate_get(url, headers=auth_hdr)
|
result = falcontest.simulate_get(url, headers=auth_hdr)
|
||||||
|
@ -47,7 +48,8 @@ class TestClass(object):
|
||||||
|
|
||||||
def test_bootaction_context_noauth(self, falcontest, seed_bootaction):
|
def test_bootaction_context_noauth(self, falcontest, seed_bootaction):
|
||||||
"""Test that the API will return a boot action context"""
|
"""Test that the API will return a boot action context"""
|
||||||
url = "/api/v1.0/bootactions/nodes/%s/units" % seed_bootaction['nodename']
|
url = "/api/v1.0/bootactions/nodes/%s/units" % seed_bootaction[
|
||||||
|
'nodename']
|
||||||
|
|
||||||
result = falcontest.simulate_get(url)
|
result = falcontest.simulate_get(url)
|
||||||
|
|
||||||
|
@ -55,7 +57,8 @@ class TestClass(object):
|
||||||
|
|
||||||
def test_bootaction_context_badauth(self, falcontest, seed_bootaction):
|
def test_bootaction_context_badauth(self, falcontest, seed_bootaction):
|
||||||
"""Test that the API will return a boot action context"""
|
"""Test that the API will return a boot action context"""
|
||||||
url = "/api/v1.0/bootactions/nodes/%s/units" % seed_bootaction['nodename']
|
url = "/api/v1.0/bootactions/nodes/%s/units" % seed_bootaction[
|
||||||
|
'nodename']
|
||||||
auth_hdr = {'X-Bootaction-Key': 'deadbeef'}
|
auth_hdr = {'X-Bootaction-Key': 'deadbeef'}
|
||||||
|
|
||||||
result = falcontest.simulate_get(url, headers=auth_hdr)
|
result = falcontest.simulate_get(url, headers=auth_hdr)
|
||||||
|
|
|
@ -90,9 +90,8 @@ class TestBuildData(object):
|
||||||
}
|
}
|
||||||
|
|
||||||
build_data_old = copy.deepcopy(build_data_latest)
|
build_data_old = copy.deepcopy(build_data_latest)
|
||||||
build_data_old[
|
build_data_old['collected_date'] = build_data_latest[
|
||||||
'collected_date'] = build_data_latest['collected_date'] - timedelta(
|
'collected_date'] - timedelta(days=1)
|
||||||
days=1)
|
|
||||||
build_data_old['task_id'] = uuid.uuid4()
|
build_data_old['task_id'] = uuid.uuid4()
|
||||||
|
|
||||||
build_data1 = objects.BuildData(**build_data_latest)
|
build_data1 = objects.BuildData(**build_data_latest)
|
||||||
|
|
|
@ -25,16 +25,14 @@ PROM_URL = urlparse('http://promhost:80/api/v1.0')
|
||||||
PROM_HOST = 'promhost'
|
PROM_HOST = 'promhost'
|
||||||
|
|
||||||
|
|
||||||
@mock.patch(
|
@mock.patch('drydock_provisioner.drivers.kubernetes'
|
||||||
'drydock_provisioner.drivers.kubernetes'
|
'.promenade_driver.promenade_client'
|
||||||
'.promenade_driver.promenade_client'
|
'.PromenadeSession._get_prom_url',
|
||||||
'.PromenadeSession._get_prom_url',
|
return_value=PROM_URL)
|
||||||
return_value=PROM_URL)
|
@mock.patch('drydock_provisioner.drivers.kubernetes'
|
||||||
@mock.patch(
|
'.promenade_driver.promenade_client'
|
||||||
'drydock_provisioner.drivers.kubernetes'
|
'.PromenadeSession.set_auth',
|
||||||
'.promenade_driver.promenade_client'
|
return_value=None)
|
||||||
'.PromenadeSession.set_auth',
|
|
||||||
return_value=None)
|
|
||||||
@responses.activate
|
@responses.activate
|
||||||
def test_put(patch1, patch2):
|
def test_put(patch1, patch2):
|
||||||
"""
|
"""
|
||||||
|
@ -47,51 +45,43 @@ def test_put(patch1, patch2):
|
||||||
status=200)
|
status=200)
|
||||||
|
|
||||||
prom_session = PromenadeSession()
|
prom_session = PromenadeSession()
|
||||||
result = prom_session.put('v1.0/node-label/n1',
|
result = prom_session.put(
|
||||||
body='{"key1":"label1"}',
|
'v1.0/node-label/n1', body='{"key1":"label1"}', timeout=(60, 60))
|
||||||
timeout=(60, 60))
|
|
||||||
|
|
||||||
assert PROM_HOST == prom_session.host
|
assert PROM_HOST == prom_session.host
|
||||||
assert result.status_code == 200
|
assert result.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
@mock.patch(
|
@mock.patch('drydock_provisioner.drivers.kubernetes'
|
||||||
'drydock_provisioner.drivers.kubernetes'
|
'.promenade_driver.promenade_client'
|
||||||
'.promenade_driver.promenade_client'
|
'.PromenadeSession._get_prom_url',
|
||||||
'.PromenadeSession._get_prom_url',
|
return_value=PROM_URL)
|
||||||
return_value=PROM_URL)
|
@mock.patch('drydock_provisioner.drivers.kubernetes'
|
||||||
@mock.patch(
|
'.promenade_driver.promenade_client'
|
||||||
'drydock_provisioner.drivers.kubernetes'
|
'.PromenadeSession.set_auth',
|
||||||
'.promenade_driver.promenade_client'
|
return_value=None)
|
||||||
'.PromenadeSession.set_auth',
|
|
||||||
return_value=None)
|
|
||||||
@responses.activate
|
@responses.activate
|
||||||
def test_get(patch1, patch2):
|
def test_get(patch1, patch2):
|
||||||
"""
|
"""
|
||||||
Test get functionality
|
Test get functionality
|
||||||
"""
|
"""
|
||||||
responses.add(
|
responses.add(
|
||||||
responses.GET,
|
responses.GET, 'http://promhost:80/api/v1.0/node-label/n1', status=200)
|
||||||
'http://promhost:80/api/v1.0/node-label/n1',
|
|
||||||
status=200)
|
|
||||||
|
|
||||||
prom_session = PromenadeSession()
|
prom_session = PromenadeSession()
|
||||||
result = prom_session.get('v1.0/node-label/n1',
|
result = prom_session.get('v1.0/node-label/n1', timeout=(60, 60))
|
||||||
timeout=(60, 60))
|
|
||||||
|
|
||||||
assert result.status_code == 200
|
assert result.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
@mock.patch(
|
@mock.patch('drydock_provisioner.drivers.kubernetes'
|
||||||
'drydock_provisioner.drivers.kubernetes'
|
'.promenade_driver.promenade_client'
|
||||||
'.promenade_driver.promenade_client'
|
'.PromenadeSession._get_prom_url',
|
||||||
'.PromenadeSession._get_prom_url',
|
return_value=PROM_URL)
|
||||||
return_value=PROM_URL)
|
@mock.patch('drydock_provisioner.drivers.kubernetes'
|
||||||
@mock.patch(
|
'.promenade_driver.promenade_client'
|
||||||
'drydock_provisioner.drivers.kubernetes'
|
'.PromenadeSession.set_auth',
|
||||||
'.promenade_driver.promenade_client'
|
return_value=None)
|
||||||
'.PromenadeSession.set_auth',
|
|
||||||
return_value=None)
|
|
||||||
@responses.activate
|
@responses.activate
|
||||||
def test_post(patch1, patch2):
|
def test_post(patch1, patch2):
|
||||||
"""
|
"""
|
||||||
|
@ -104,24 +94,21 @@ def test_post(patch1, patch2):
|
||||||
status=200)
|
status=200)
|
||||||
|
|
||||||
prom_session = PromenadeSession()
|
prom_session = PromenadeSession()
|
||||||
result = prom_session.post('v1.0/node-label/n1',
|
result = prom_session.post(
|
||||||
body='{"key1":"label1"}',
|
'v1.0/node-label/n1', body='{"key1":"label1"}', timeout=(60, 60))
|
||||||
timeout=(60, 60))
|
|
||||||
|
|
||||||
assert PROM_HOST == prom_session.host
|
assert PROM_HOST == prom_session.host
|
||||||
assert result.status_code == 200
|
assert result.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
@mock.patch(
|
@mock.patch('drydock_provisioner.drivers.kubernetes'
|
||||||
'drydock_provisioner.drivers.kubernetes'
|
'.promenade_driver.promenade_client'
|
||||||
'.promenade_driver.promenade_client'
|
'.PromenadeSession._get_prom_url',
|
||||||
'.PromenadeSession._get_prom_url',
|
return_value=PROM_URL)
|
||||||
return_value=PROM_URL)
|
@mock.patch('drydock_provisioner.drivers.kubernetes'
|
||||||
@mock.patch(
|
'.promenade_driver.promenade_client'
|
||||||
'drydock_provisioner.drivers.kubernetes'
|
'.PromenadeSession.set_auth',
|
||||||
'.promenade_driver.promenade_client'
|
return_value=None)
|
||||||
'.PromenadeSession.set_auth',
|
|
||||||
return_value=None)
|
|
||||||
@responses.activate
|
@responses.activate
|
||||||
def test_relabel_node(patch1, patch2):
|
def test_relabel_node(patch1, patch2):
|
||||||
"""
|
"""
|
||||||
|
@ -141,16 +128,14 @@ def test_relabel_node(patch1, patch2):
|
||||||
assert result == {"key1": "label1"}
|
assert result == {"key1": "label1"}
|
||||||
|
|
||||||
|
|
||||||
@mock.patch(
|
@mock.patch('drydock_provisioner.drivers.kubernetes'
|
||||||
'drydock_provisioner.drivers.kubernetes'
|
'.promenade_driver.promenade_client'
|
||||||
'.promenade_driver.promenade_client'
|
'.PromenadeSession._get_prom_url',
|
||||||
'.PromenadeSession._get_prom_url',
|
return_value=PROM_URL)
|
||||||
return_value=PROM_URL)
|
@mock.patch('drydock_provisioner.drivers.kubernetes'
|
||||||
@mock.patch(
|
'.promenade_driver.promenade_client'
|
||||||
'drydock_provisioner.drivers.kubernetes'
|
'.PromenadeSession.set_auth',
|
||||||
'.promenade_driver.promenade_client'
|
return_value=None)
|
||||||
'.PromenadeSession.set_auth',
|
|
||||||
return_value=None)
|
|
||||||
@responses.activate
|
@responses.activate
|
||||||
def test_relabel_node_403_status(patch1, patch2):
|
def test_relabel_node_403_status(patch1, patch2):
|
||||||
"""
|
"""
|
||||||
|
@ -167,16 +152,15 @@ def test_relabel_node_403_status(patch1, patch2):
|
||||||
with pytest.raises(errors.ClientForbiddenError):
|
with pytest.raises(errors.ClientForbiddenError):
|
||||||
prom_client.relabel_node('n1', {"key1": "label1"})
|
prom_client.relabel_node('n1', {"key1": "label1"})
|
||||||
|
|
||||||
@mock.patch(
|
|
||||||
'drydock_provisioner.drivers.kubernetes'
|
@mock.patch('drydock_provisioner.drivers.kubernetes'
|
||||||
'.promenade_driver.promenade_client'
|
'.promenade_driver.promenade_client'
|
||||||
'.PromenadeSession._get_prom_url',
|
'.PromenadeSession._get_prom_url',
|
||||||
return_value=PROM_URL)
|
return_value=PROM_URL)
|
||||||
@mock.patch(
|
@mock.patch('drydock_provisioner.drivers.kubernetes'
|
||||||
'drydock_provisioner.drivers.kubernetes'
|
'.promenade_driver.promenade_client'
|
||||||
'.promenade_driver.promenade_client'
|
'.PromenadeSession.set_auth',
|
||||||
'.PromenadeSession.set_auth',
|
return_value=None)
|
||||||
return_value=None)
|
|
||||||
@responses.activate
|
@responses.activate
|
||||||
def test_relabel_node_401_status(patch1, patch2):
|
def test_relabel_node_401_status(patch1, patch2):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue