Merge pull request #1 from jayofdoom/jay/ExampleBusinessLogicManager

Add example business logic hardware manager
This commit is contained in:
Jay Faulkner 2016-06-10 17:02:33 -07:00 committed by GitHub
commit 8fc36d5a6a
3 changed files with 145 additions and 0 deletions

47
README.rst Normal file
View File

@ -0,0 +1,47 @@
ipa-example-hardware-managers
=============================
Example hardware managers for use with the `ironic python agent <http://git.openstack.org/cgit/openstack/ironic-python-agent>`_.
Examples and Use Cases Provided
===============================
Example Device Hardware Manager
-------------------------------
This example manager is meant to demonstrate good patterns for developing a
device-specific hardware manager, such as for a specific version of NIC or
disk.
Use Cases include:
* Adding device-specific clean-steps, such as to flash firmware or
verify it's still properly working after being provisioned.
* Implementing erase_device() using a vendor-provided utility for a given
disk model.
Example Business Logic Hardware Manager
---------------------------------------
This example manager is meant to demonstrate how cleaning and the agent can
use the node object and the node itself to enforce business logic and node
consistency.
Use Cases include:
* Quality control on hardware by ensuring no component is beyond its useful
life.
* Asserting truths about the node; such as number of disks or total RAM.
* Reporting metrics about the node's hardware state.
* Overriding logic of get_os_install_device().
Make your own Manager based on these
====================================
To make your own hardware manager based on these examples, copy or fork the
relevant examples out of this repository. Modify classnames and entrypoints
in setup.cfg to be not-examples.
Since the entrypoints are defined in setup.cfg, simply installing your new
python package alongside IPA in a custom ramdisk should be enough to enable
the new hardware manager.

View File

@ -0,0 +1,97 @@
# Copyright 2015 Rackspace, 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 time
from ironic_python_agent import errors
from ironic_python_agent import hardware
from oslo_log import log
LOG = log.getLogger()
class ExampleBusinessLogicHardwareManager(hardware.HardwareManager):
"""Example hardware manager to enforce business logic"""
# All hardware managers have a name and a version.
# Version should be bumped anytime a change is introduced. This will
# signal to Ironic that if automatic node cleaning is in progress to
# restart it from the beginning, to ensure consistency. The value can
# be anything; it's checked for equality against previously seen
# name:manager pairs.
HARDWARE_MANAGER_NAME = 'ExampleBusinessLogicHardwareManager'
HARDWARE_MANAGER_VERSION = '1'
def evaluate_hardware_support(self):
"""Declare level of hardware support provided.
Since this example is explicitly about enforcing business logic during
cleaning, we want to return a static value.
:returns: HardwareSupport level for this manager.
"""
return hardware.HardwareSupport.SERVICE_PROVIDER
def get_clean_steps(self, node, ports):
"""Get a list of clean steps with priority.
Define any clean steps added by this manager here. These will be mixed
with other loaded managers that support this hardware, and ordered by
priority. Higher priority steps run earlier.
Note that out-of-band clean steps may also be provided by Ironic.
These will follow the same priority ordering even though they are not
executed by IPA.
There is *no guarantee whatsoever* that steps defined here will be
executed by this HardwareManager. When it comes time to run these
steps, they'll be called using dispatch_to_managers() just like any
other IPA HardwareManager method. This means if they are unique to
your hardware, they should be uniquely named. For example,
upgrade_firmware would be a bad step name. Whereas
upgrade_foobar_device_firmware would be better.
:param node: The node object as provided by Ironic.
:param ports: Port objects as provided by Ironic.
:returns: A list of cleaning steps, as a list of dicts.
"""
# While obviously you could actively run code here, generally this
# should just return a static value, as any initialization and
# detection should've been done in evaluate_hardware_support().
return [{
'step': 'companyx_verify_device_lifecycle',
'priority': 472,
# If you need Ironic to coordinate a reboot after this step
# runs, but before continuing cleaning, this should be true.
'reboot_requested': False,
# If it's safe for Ironic to abort cleaning while this step
# runs, this should be true.
'abortable': True
}]
# Other examples of interesting cleaning steps for this kind of hardware
# manager would include verifying node.properties matches current state of
# the node, checking smart stats to ensure the disk is not soon to fail,
# or enforcing security policies.
def companyx_verify_device_lifecycle(self, node, ports):
"""Verify node is not beyond useful life of 3 years."""
create_date = node.get('created_at')
if create_date is not None:
server_age = time.time() - time.mktime(time.strptime(create_date))
if server_age > (60 * 60 * 24 * 365 * 3):
raise errors.CleaningError(
'Server is too old to pass cleaning!')
else:
LOG.info('Node is %s seconds old, younger than 3 years, '
'cleaning passes.', server_age)

View File

@ -18,3 +18,4 @@ packages =
[entry_points]
ironic_python_agent.hardware_managers =
example_device = example_hardware_managers.example_device:ExampleDeviceHardwareManager
example_business_logic = example_hardware_managers.example_business_logic:ExampleBusinessLogicHardwareManager