Some small improvements to pass pep8 and pep257.
This is just the first run. Change-Id: If47a475b03d367a4e04f54ef31845e70d46f188c
This commit is contained in:
parent
fb00359b51
commit
444ebaa26f
|
@ -0,0 +1,15 @@
|
||||||
|
"""Common module for osha."""
|
||||||
|
|
||||||
|
# (c) Copyright 2016 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# 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.
|
|
@ -1,4 +1,6 @@
|
||||||
# (c) Copyright 2014,2015 Hewlett-Packard Development Company, L.P.
|
"""Manage all configuration the OpenStack way."""
|
||||||
|
|
||||||
|
# (c) Copyright 2016 Hewlett-Packard Development Company, L.P.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
@ -11,12 +13,15 @@
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
from oslo_config import cfg
|
|
||||||
from osha.common.utils import env
|
|
||||||
import sys
|
import sys
|
||||||
from osha import __version__ as OSHA_VERSION
|
|
||||||
|
from oslo_config import cfg
|
||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
|
|
||||||
|
from osha import __version__ as OSHA_VERSION
|
||||||
|
from osha.common.utils import env
|
||||||
|
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
|
|
||||||
_MONITORS = [
|
_MONITORS = [
|
||||||
|
@ -32,11 +37,10 @@ _MONITORS = [
|
||||||
cfg.DictOpt('kwargs',
|
cfg.DictOpt('kwargs',
|
||||||
default={},
|
default={},
|
||||||
help='List of kwargs if you want to pass it to initialize'
|
help='List of kwargs if you want to pass it to initialize'
|
||||||
' the monitoring driver. should be provided in key:value '
|
' the monitoring driver. should be provided in key:value '
|
||||||
'format')
|
'format')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
_COMMON = [
|
_COMMON = [
|
||||||
cfg.IntOpt('wait',
|
cfg.IntOpt('wait',
|
||||||
default=30,
|
default=30,
|
||||||
|
@ -46,93 +50,92 @@ _COMMON = [
|
||||||
_FENCER = [
|
_FENCER = [
|
||||||
cfg.StrOpt('credentials-file',
|
cfg.StrOpt('credentials-file',
|
||||||
help='YAML File contains the required credentials for compute '
|
help='YAML File contains the required credentials for compute '
|
||||||
'nodes'),
|
'nodes'),
|
||||||
cfg.IntOpt('retries',
|
cfg.IntOpt('retries',
|
||||||
default=1,
|
default=1,
|
||||||
help='Number of retries to fence the each compute node. Must be'
|
help='Number of retries to fence the each compute node. Must be'
|
||||||
' at least 1 to try first the soft shutdown'),
|
' at least 1 to try first the soft shutdown'),
|
||||||
cfg.IntOpt('hold-period',
|
cfg.IntOpt('hold-period',
|
||||||
default=10,
|
default=10,
|
||||||
help='Time in seconds to wait between retries. Should be '
|
help='Time in seconds to wait between retries. Should be '
|
||||||
'reasonable amount of time as different servers take '
|
'reasonable amount of time as different servers take '
|
||||||
'different times to shut off'),
|
'different times to shut off'),
|
||||||
cfg.StrOpt('driver',
|
cfg.StrOpt('driver',
|
||||||
default='osha.fencers.drivers.ipmi.driver.IpmiDriver',
|
default='osha.fencers.drivers.ipmi.driver.IpmiDriver',
|
||||||
help='Choose the best fencer driver i.e.(ipmi, libvirt, ..'),
|
help='Choose the best fencer driver i.e.(ipmi, libvirt, ..'),
|
||||||
cfg.DictOpt('options',
|
cfg.DictOpt('options',
|
||||||
default={},
|
default={},
|
||||||
help='List of kwargs to customize the fencer operation. You '
|
help='List of kwargs to customize the fencer operation. You '
|
||||||
'fencer driver should support these options. Options '
|
'fencer driver should support these options. Options '
|
||||||
'should be in key:value format')
|
'should be in key:value format')
|
||||||
]
|
]
|
||||||
|
|
||||||
_KEYSTONE_AUTH_TOKEN = [
|
_KEYSTONE_AUTH_TOKEN = [
|
||||||
cfg.StrOpt('auth_uri',
|
cfg.StrOpt('auth_uri',
|
||||||
help='Openstack auth URI i.e. http://controller:5000',
|
help='Openstack auth URI i.e. http://controller:5000',
|
||||||
dest='auth_uri'),
|
dest='auth_uri'), cfg.StrOpt(
|
||||||
cfg.StrOpt('auth_url',
|
'auth_url',
|
||||||
help='Openstack auth URL i.e. http://controller:35357/v3',
|
help='Openstack auth URL i.e. http://controller:35357/v3',
|
||||||
dest='auth_url'),
|
dest='auth_url'),
|
||||||
cfg.StrOpt('auth_plugin',
|
cfg.StrOpt('auth_plugin',
|
||||||
help='Openstack auth plugin i.e. ( password, token, ...) '
|
help='Openstack auth plugin i.e. ( password, token, ...) '
|
||||||
'password is the only available plugin for the time being',
|
'password is the only available plugin for the time being',
|
||||||
dest='auth_plugin'),
|
dest='auth_plugin'), cfg.StrOpt('username',
|
||||||
cfg.StrOpt('username',
|
help='Openstack username',
|
||||||
help='Openstack username',
|
dest='username'),
|
||||||
dest='username'),
|
|
||||||
cfg.StrOpt('password',
|
cfg.StrOpt('password',
|
||||||
help='Openstack Password',
|
help='Openstack Password',
|
||||||
dest='password'),
|
dest='password'), cfg.StrOpt('project_name',
|
||||||
cfg.StrOpt('project_name',
|
help='Openstack Project Name.',
|
||||||
help='Openstack Project Name.',
|
dest='project_name'),
|
||||||
dest='project_name'),
|
|
||||||
cfg.StrOpt('domain_name',
|
cfg.StrOpt('domain_name',
|
||||||
help='Openstack domain Name.',
|
help='Openstack domain Name.',
|
||||||
dest='domain_name'),
|
dest='domain_name'), cfg.StrOpt(
|
||||||
cfg.StrOpt('project_domain_id',
|
'project_domain_id',
|
||||||
help='Openstack Project Domain id, default is Default',
|
help='Openstack Project Domain id, default is Default',
|
||||||
dest='project_domain_id'),
|
dest='project_domain_id'),
|
||||||
cfg.StrOpt('user_domain_id',
|
cfg.StrOpt('user_domain_id',
|
||||||
help='Openstack user Domain id, default is Default',
|
help='Openstack user Domain id, default is Default',
|
||||||
dest='user_domain_id'),
|
dest='user_domain_id'), cfg.StrOpt(
|
||||||
cfg.StrOpt('project_domain_name',
|
'project_domain_name',
|
||||||
help='Openstack Project Domain name, default is Default',
|
help='Openstack Project Domain name, default is Default',
|
||||||
dest='project_domain_name'),
|
dest='project_domain_name'), cfg.StrOpt(
|
||||||
cfg.StrOpt('user_domain_name',
|
'user_domain_name',
|
||||||
help='Openstack user Domain name, default is Default',
|
help='Openstack user Domain name, default is Default',
|
||||||
dest='user_domain_name'),
|
dest='user_domain_name'),
|
||||||
cfg.DictOpt('kwargs',
|
cfg.DictOpt('kwargs',
|
||||||
help='Openstack Authentication arguments you can pass it here '
|
help='Openstack Authentication arguments you can pass it here '
|
||||||
'as Key:Value, Key1:Value1, ... ',
|
'as Key:Value, Key1:Value1, ... ',
|
||||||
dest='kwargs',
|
dest='kwargs',
|
||||||
default={})
|
default={})
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
_EVACUATION = [
|
_EVACUATION = [
|
||||||
cfg.StrOpt('driver',
|
cfg.StrOpt(
|
||||||
default='osha.evacuators.drivers.osha.standard.'
|
'driver',
|
||||||
'OshaStandardEvacuator',
|
default='osha.evacuators.drivers.osha.standard.'
|
||||||
help='Time in seconds to wait between retries to disable compute'
|
'OshaStandardEvacuator',
|
||||||
' node or put it in maintenance mode. Default 10 seconds',
|
help='Time in seconds to wait between retries to disable compute'
|
||||||
dest='driver'),
|
' node or put it in maintenance mode. Default 10 seconds',
|
||||||
cfg.IntOpt('wait',
|
dest='driver'), cfg.IntOpt(
|
||||||
default=10,
|
'wait',
|
||||||
help='Time in seconds to wait between retries to disable compute'
|
default=10,
|
||||||
' node or put it in maintenance mode. Default 10 seconds',
|
help='Time in seconds to wait between retries to disable compute'
|
||||||
dest='wait'),
|
' node or put it in maintenance mode. Default 10 seconds',
|
||||||
|
dest='wait'),
|
||||||
cfg.IntOpt('retries',
|
cfg.IntOpt('retries',
|
||||||
default=1,
|
default=1,
|
||||||
help='Number of retries to put node in maintenance mode before '
|
help='Number of retries to put node in maintenance mode before '
|
||||||
'reporting failure to evacuate the node',
|
'reporting failure to evacuate the node',
|
||||||
dest='retries'),
|
dest='retries'),
|
||||||
cfg.DictOpt('options',
|
cfg.DictOpt(
|
||||||
default={},
|
'options',
|
||||||
help='Dict contains kwargs to be passed to the evacuator driver'
|
default={},
|
||||||
'. In case you have additional args needs to be passed to '
|
help='Dict contains kwargs to be passed to the evacuator driver'
|
||||||
'your evacuator please, list them as key0:value0, '
|
'. In case you have additional args needs to be passed to '
|
||||||
'key1:value1, ....',
|
'your evacuator please, list them as key0:value0, '
|
||||||
dest='options')
|
'key1:value1, ....',
|
||||||
|
dest='options')
|
||||||
]
|
]
|
||||||
|
|
||||||
_NOTIFIERS = [
|
_NOTIFIERS = [
|
||||||
|
@ -140,121 +143,124 @@ _NOTIFIERS = [
|
||||||
default='osha.notifiers.drivers.osha.default_email.OshaEmail',
|
default='osha.notifiers.drivers.osha.default_email.OshaEmail',
|
||||||
dest='driver',
|
dest='driver',
|
||||||
help='Notification driver to load it to notify users '
|
help='Notification driver to load it to notify users '
|
||||||
'if something went wrong'),
|
'if something went wrong'),
|
||||||
cfg.StrOpt('endpoint',
|
cfg.StrOpt('endpoint',
|
||||||
default=None,
|
default=None,
|
||||||
dest='endpoint',
|
dest='endpoint',
|
||||||
help='Endpoint URL for the notification system. If you the '
|
help='Endpoint URL for the notification system. If you the '
|
||||||
'driver you are using doesnot require any URL just comment '
|
'driver you are using doesnot require any URL just comment '
|
||||||
'it or use none'),
|
'it or use none'),
|
||||||
cfg.StrOpt('username',
|
cfg.StrOpt(
|
||||||
default=None,
|
'username',
|
||||||
dest='username',
|
default=None,
|
||||||
help='Username to authenticate against the notification system. '
|
dest='username',
|
||||||
'If the driver you are using doesnot require any '
|
help='Username to authenticate against the notification system. '
|
||||||
'authentications comment or use None'),
|
'If the driver you are using doesnot require any '
|
||||||
cfg.StrOpt('password',
|
'authentications comment or use None'), cfg.StrOpt(
|
||||||
default=None,
|
'password',
|
||||||
dest='password',
|
default=None,
|
||||||
help='Password to authenticate against the notification system. '
|
dest='password',
|
||||||
'If the driver you are using doesnot require any '
|
help='Password to authenticate against the notification system. '
|
||||||
'authentications comment or use None'),
|
'If the driver you are using doesnot require any '
|
||||||
|
'authentications comment or use None'),
|
||||||
cfg.StrOpt('templates-dir',
|
cfg.StrOpt('templates-dir',
|
||||||
dest='templates-dir',
|
dest='templates-dir',
|
||||||
default='/etc/osha/templates',
|
default='/etc/osha/templates',
|
||||||
help='Path to Jinja2 templates directory that contains '
|
help='Path to Jinja2 templates directory that contains '
|
||||||
'message templates'),
|
'message templates'),
|
||||||
cfg.DictOpt('options',
|
cfg.DictOpt('options',
|
||||||
default={},
|
default={},
|
||||||
dest='options',
|
dest='options',
|
||||||
help='Key:Value Kwargs to pass it to the notification driver, '
|
help='Key:Value Kwargs to pass it to the notification driver, '
|
||||||
'if you want to pass any special arguments for your '
|
'if you want to pass any special arguments for your '
|
||||||
'driver. '),
|
'driver. '),
|
||||||
cfg.ListOpt('notify-list',
|
cfg.ListOpt('notify-list',
|
||||||
default=[],
|
default=[],
|
||||||
dest='notify-list',
|
dest='notify-list',
|
||||||
help='List of emails to sent them notification if something '
|
help='List of emails to sent them notification if something '
|
||||||
'went wrong and Osha wasnot able to send an email to the '
|
'went wrong and Osha wasnot able to send an email to the '
|
||||||
'tenant admin'),
|
'tenant admin'),
|
||||||
cfg.StrOpt('notify-from',
|
cfg.StrOpt('notify-from',
|
||||||
dest='notify-from',
|
dest='notify-from',
|
||||||
help='The sender address, it can be email address if we used '
|
help='The sender address, it can be email address if we used '
|
||||||
'default email driver, or phone number if we use sms '
|
'default email driver, or phone number if we use sms '
|
||||||
'gateway for example.')
|
'gateway for example.')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def build_os_options():
|
def build_os_options():
|
||||||
|
"""Build oslo options related to OpenStack environment."""
|
||||||
osclient_opts = [
|
osclient_opts = [
|
||||||
cfg.StrOpt('os-username',
|
cfg.StrOpt('os-username',
|
||||||
default=env('OS_USERNAME'),
|
default=env('OS_USERNAME'),
|
||||||
help='Name used for authentication with the OpenStack '
|
help='Name used for authentication with the OpenStack '
|
||||||
'Identity service. Defaults to env[OS_USERNAME].',
|
'Identity service. Defaults to env[OS_USERNAME].',
|
||||||
dest='os_username'),
|
dest='os_username'),
|
||||||
cfg.StrOpt('os-password',
|
cfg.StrOpt('os-password',
|
||||||
default=env('OS_PASSWORD'),
|
default=env('OS_PASSWORD'),
|
||||||
help='Password used for authentication with the OpenStack '
|
help='Password used for authentication with the OpenStack '
|
||||||
'Identity service. Defaults to env[OS_PASSWORD].',
|
'Identity service. Defaults to env[OS_PASSWORD].',
|
||||||
dest='os_password'),
|
dest='os_password'),
|
||||||
cfg.StrOpt('os-project-name',
|
cfg.StrOpt('os-project-name',
|
||||||
default=env('OS_PROJECT_NAME'),
|
default=env('OS_PROJECT_NAME'),
|
||||||
help='Project name to scope to. Defaults to '
|
help='Project name to scope to. Defaults to '
|
||||||
'env[OS_PROJECT_NAME].',
|
'env[OS_PROJECT_NAME].',
|
||||||
dest='os_project_name'),
|
dest='os_project_name'),
|
||||||
cfg.StrOpt('os-project-domain-name',
|
cfg.StrOpt('os-project-domain-name',
|
||||||
default=env('OS_PROJECT_DOMAIN_NAME'),
|
default=env('OS_PROJECT_DOMAIN_NAME'),
|
||||||
help='Domain name containing project. Defaults to '
|
help='Domain name containing project. Defaults to '
|
||||||
'env[OS_PROJECT_DOMAIN_NAME].',
|
'env[OS_PROJECT_DOMAIN_NAME].',
|
||||||
dest='os_project_domain_name'),
|
dest='os_project_domain_name'),
|
||||||
cfg.StrOpt('os-user-domain-name',
|
cfg.StrOpt('os-user-domain-name',
|
||||||
default=env('OS_USER_DOMAIN_NAME'),
|
default=env('OS_USER_DOMAIN_NAME'),
|
||||||
help='User\'s domain name. Defaults to '
|
help='User\'s domain name. Defaults to '
|
||||||
'env[OS_USER_DOMAIN_NAME].',
|
'env[OS_USER_DOMAIN_NAME].',
|
||||||
dest='os_user_domain_name'),
|
dest='os_user_domain_name'),
|
||||||
cfg.StrOpt('os-tenant-name',
|
cfg.StrOpt('os-tenant-name',
|
||||||
default=env('OS_TENANT_NAME'),
|
default=env('OS_TENANT_NAME'),
|
||||||
help='Tenant to request authorization on. Defaults to '
|
help='Tenant to request authorization on. Defaults to '
|
||||||
'env[OS_TENANT_NAME].',
|
'env[OS_TENANT_NAME].',
|
||||||
dest='os_tenant_name'),
|
dest='os_tenant_name'),
|
||||||
cfg.StrOpt('os-tenant-id',
|
cfg.StrOpt('os-tenant-id',
|
||||||
default=env('OS_TENANT_ID'),
|
default=env('OS_TENANT_ID'),
|
||||||
help='Tenant to request authorization on. Defaults to '
|
help='Tenant to request authorization on. Defaults to '
|
||||||
'env[OS_TENANT_ID].',
|
'env[OS_TENANT_ID].',
|
||||||
dest='os_tenant_id'),
|
dest='os_tenant_id'),
|
||||||
cfg.StrOpt('os-auth-url',
|
cfg.StrOpt('os-auth-url',
|
||||||
default=env('OS_AUTH_URL'),
|
default=env('OS_AUTH_URL'),
|
||||||
help='Specify the Identity endpoint to use for '
|
help='Specify the Identity endpoint to use for '
|
||||||
'authentication. Defaults to env[OS_AUTH_URL].',
|
'authentication. Defaults to env[OS_AUTH_URL].',
|
||||||
dest='os_auth_url'),
|
dest='os_auth_url'),
|
||||||
cfg.StrOpt('os-backup-url',
|
cfg.StrOpt('os-backup-url',
|
||||||
default=env('OS_BACKUP_URL'),
|
default=env('OS_BACKUP_URL'),
|
||||||
help='Specify the Freezer backup service endpoint to use. '
|
help='Specify the Freezer backup service endpoint to use. '
|
||||||
'Defaults to env[OS_BACKUP_URL].',
|
'Defaults to env[OS_BACKUP_URL].',
|
||||||
dest='os_backup_url'),
|
dest='os_backup_url'),
|
||||||
cfg.StrOpt('os-region-name',
|
cfg.StrOpt('os-region-name',
|
||||||
default=env('OS_REGION_NAME'),
|
default=env('OS_REGION_NAME'),
|
||||||
help='Specify the region to use. Defaults to '
|
help='Specify the region to use. Defaults to '
|
||||||
'env[OS_REGION_NAME].',
|
'env[OS_REGION_NAME].',
|
||||||
dest='os_region_name'),
|
dest='os_region_name'),
|
||||||
cfg.StrOpt('os-token',
|
cfg.StrOpt(
|
||||||
default=env('OS_TOKEN'),
|
'os-token',
|
||||||
help='Specify an existing token to use instead of retrieving'
|
default=env('OS_TOKEN'),
|
||||||
' one via authentication (e.g. with username & '
|
help='Specify an existing token to use instead of retrieving'
|
||||||
'password). Defaults to env[OS_TOKEN].',
|
' one via authentication (e.g. with username & '
|
||||||
dest='os_token'),
|
'password). Defaults to env[OS_TOKEN].',
|
||||||
|
dest='os_token'),
|
||||||
cfg.StrOpt('os-identity-api-version',
|
cfg.StrOpt('os-identity-api-version',
|
||||||
default=env('OS_IDENTITY_API_VERSION'),
|
default=env('OS_IDENTITY_API_VERSION'),
|
||||||
help='Identity API version: 2.0 or 3. '
|
help='Identity API version: 2.0 or 3. '
|
||||||
'Defaults to env[OS_IDENTITY_API_VERSION]',
|
'Defaults to env[OS_IDENTITY_API_VERSION]',
|
||||||
dest='os_identity_api_version'),
|
dest='os_identity_api_version'),
|
||||||
cfg.StrOpt('os-endpoint-type',
|
cfg.StrOpt('os-endpoint-type',
|
||||||
choices=['public', 'publicURL', 'internal', 'internalURL',
|
choices=['public', 'publicURL', 'internal', 'internalURL',
|
||||||
'admin', 'adminURL'],
|
'admin', 'adminURL'],
|
||||||
default=env('OS_ENDPOINT_TYPE') or 'public',
|
default=env('OS_ENDPOINT_TYPE') or 'public',
|
||||||
help='Endpoint type to select. Valid endpoint types: '
|
help='Endpoint type to select. Valid endpoint types: '
|
||||||
'"public" or "publicURL", "internal" or "internalURL",'
|
'"public" or "publicURL", "internal" or "internalURL",'
|
||||||
' "admin" or "adminURL". Defaults to '
|
' "admin" or "adminURL". Defaults to '
|
||||||
'env[OS_ENDPOINT_TYPE] or "public"',
|
'env[OS_ENDPOINT_TYPE] or "public"',
|
||||||
dest='os_endpoint_type'),
|
dest='os_endpoint_type'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -262,19 +268,20 @@ def build_os_options():
|
||||||
|
|
||||||
|
|
||||||
def configure():
|
def configure():
|
||||||
|
"""Register configuration."""
|
||||||
CONF.register_cli_opts(build_os_options())
|
CONF.register_cli_opts(build_os_options())
|
||||||
CONF.register_opts(_COMMON)
|
CONF.register_opts(_COMMON)
|
||||||
monitors_grp = cfg.OptGroup('monitoring',
|
monitors_grp = cfg.OptGroup('monitoring',
|
||||||
title='Monitoring',
|
title='Monitoring',
|
||||||
help='Monitoring Driver/plugin to be used to '
|
help='Monitoring Driver/plugin to be used to '
|
||||||
'monitor compute nodes')
|
'monitor compute nodes')
|
||||||
CONF.register_group(monitors_grp)
|
CONF.register_group(monitors_grp)
|
||||||
CONF.register_opts(_MONITORS, group='monitoring')
|
CONF.register_opts(_MONITORS, group='monitoring')
|
||||||
|
|
||||||
fencers_grp = cfg.OptGroup('fencer',
|
fencers_grp = cfg.OptGroup('fencer',
|
||||||
title='fencer Options',
|
title='fencer Options',
|
||||||
help='fencer Driver/plugin to be used to '
|
help='fencer Driver/plugin to be used to '
|
||||||
'fence compute nodes')
|
'fence compute nodes')
|
||||||
CONF.register_group(fencers_grp)
|
CONF.register_group(fencers_grp)
|
||||||
CONF.register_opts(_FENCER, group='fencer')
|
CONF.register_opts(_FENCER, group='fencer')
|
||||||
|
|
||||||
|
@ -282,16 +289,16 @@ def configure():
|
||||||
evacuators_grp = cfg.OptGroup('evacuation',
|
evacuators_grp = cfg.OptGroup('evacuation',
|
||||||
title='Evacuation Options',
|
title='Evacuation Options',
|
||||||
help='Evacuation Driver/plugin opts to be '
|
help='Evacuation Driver/plugin opts to be '
|
||||||
'used to Evacuate compute nodes')
|
'used to Evacuate compute nodes')
|
||||||
CONF.register_group(evacuators_grp)
|
CONF.register_group(evacuators_grp)
|
||||||
CONF.register_opts(_EVACUATION, group='evacuation')
|
CONF.register_opts(_EVACUATION, group='evacuation')
|
||||||
|
|
||||||
# Notification Section :)
|
# Notification Section :)
|
||||||
notifiers_grp = cfg.OptGroup('notifiers',
|
notifiers_grp = cfg.OptGroup('notifiers',
|
||||||
title='Notification Options',
|
title='Notification Options',
|
||||||
help='Notification Driver/plugin opts to be '
|
help='Notification Driver/plugin opts to be '
|
||||||
'used to Notify admins/users if failure '
|
'used to Notify admins/users if failure '
|
||||||
'happens')
|
'happens')
|
||||||
CONF.register_group(notifiers_grp)
|
CONF.register_group(notifiers_grp)
|
||||||
CONF.register_opts(_NOTIFIERS, group='notifiers')
|
CONF.register_opts(_NOTIFIERS, group='notifiers')
|
||||||
|
|
||||||
|
@ -299,32 +306,33 @@ def configure():
|
||||||
keystone_grp = cfg.OptGroup('keystone_authtoken',
|
keystone_grp = cfg.OptGroup('keystone_authtoken',
|
||||||
title='Keystone Auth Options',
|
title='Keystone Auth Options',
|
||||||
help='Openstack Credentials to call the nova '
|
help='Openstack Credentials to call the nova '
|
||||||
'APIs to evacuate ')
|
'APIs to evacuate ')
|
||||||
CONF.register_group(keystone_grp)
|
CONF.register_group(keystone_grp)
|
||||||
CONF.register_opts(_KEYSTONE_AUTH_TOKEN, group='keystone_authtoken')
|
CONF.register_opts(_KEYSTONE_AUTH_TOKEN, group='keystone_authtoken')
|
||||||
|
|
||||||
default_conf = cfg.find_config_files('osha', 'osha',
|
default_conf = cfg.find_config_files('osha', 'osha', '.conf')
|
||||||
'.conf')
|
|
||||||
log.register_options(CONF)
|
log.register_options(CONF)
|
||||||
|
|
||||||
CONF(args=sys.argv[1:],
|
CONF(args=sys.argv[1:],
|
||||||
project='osha',
|
project='osha',
|
||||||
default_config_files=default_conf,
|
default_config_files=default_conf,
|
||||||
version=OSHA_VERSION
|
version=OSHA_VERSION)
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def setup_logging():
|
def setup_logging():
|
||||||
_DEFAULT_LOG_LEVELS = ['amqp=WARN', 'amqplib=WARN', 'boto=WARN','qpid=WARN',
|
"""Set some oslo log defaults."""
|
||||||
'stevedore=WARN', 'oslo_log=INFO', 'iso8601=WARN',
|
_DEFAULT_LOG_LEVELS = ['amqp=WARN', 'amqplib=WARN', 'boto=WARN',
|
||||||
|
'qpid=WARN', 'stevedore=WARN', 'oslo_log=INFO',
|
||||||
|
'iso8601=WARN',
|
||||||
'requests.packages.urllib3.connectionpool=WARN',
|
'requests.packages.urllib3.connectionpool=WARN',
|
||||||
'urllib3.connectionpool=WARN', 'websocket=WARN',
|
'urllib3.connectionpool=WARN', 'websocket=WARN',
|
||||||
'keystonemiddleware=WARN', 'osha=INFO']
|
'keystonemiddleware=WARN', 'osha=INFO']
|
||||||
|
|
||||||
_DEFAULT_LOGGING_CONTEXT_FORMAT = ('%(asctime)s.%(msecs)03d %(process)d '
|
_DEFAULT_LOGGING_CONTEXT_FORMAT = (
|
||||||
'%(levelname)s %(name)s [%(request_id)s '
|
'%(asctime)s.%(msecs)03d %(process)d '
|
||||||
'%(user_identity)s] %(instance)s'
|
'%(levelname)s %(name)s [%(request_id)s '
|
||||||
'%(message)s')
|
'%(user_identity)s] %(instance)s'
|
||||||
|
'%(message)s')
|
||||||
log.set_defaults(_DEFAULT_LOGGING_CONTEXT_FORMAT, _DEFAULT_LOG_LEVELS)
|
log.set_defaults(_DEFAULT_LOGGING_CONTEXT_FORMAT, _DEFAULT_LOG_LEVELS)
|
||||||
log.setup(CONF, 'osha', version=OSHA_VERSION)
|
log.setup(CONF, 'osha', version=OSHA_VERSION)
|
||||||
|
|
||||||
|
@ -340,4 +348,3 @@ def list_opts():
|
||||||
}
|
}
|
||||||
|
|
||||||
return _OPTS.items()
|
return _OPTS.items()
|
||||||
|
|
||||||
|
|
|
@ -1,165 +1,183 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
"""Generic deamon."""
|
||||||
import sys, os, time, atexit
|
# (c) Copyright 2016 Hewlett-Packard Development Company, L.P.
|
||||||
from signal import SIGTERM
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import atexit
|
||||||
import logging as log
|
import logging as log
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
from signal import SIGTERM
|
||||||
class Daemon:
|
|
||||||
|
|
||||||
|
class Daemon(object):
|
||||||
|
|
||||||
|
"""A generic daemon class.
|
||||||
|
|
||||||
|
Usage: subclass the Daemon class and override the run() method
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null',
|
||||||
|
stderr='/dev/null'):
|
||||||
|
"""Instantiantion."""
|
||||||
|
self.stdin = stdin
|
||||||
|
self.stdout = stdout
|
||||||
|
self.stderr = stderr
|
||||||
|
self.pidfile = pidfile
|
||||||
|
|
||||||
|
def daemonize(self):
|
||||||
|
"""Do the UNIX double-fork magic.
|
||||||
|
|
||||||
|
See Stevens' "Advanced Programming in the UNIX Environment" for
|
||||||
|
details (ISBN 0201563177)
|
||||||
|
http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
|
||||||
"""
|
"""
|
||||||
A generic daemon class.
|
try:
|
||||||
|
pid = os.fork()
|
||||||
Usage: subclass the Daemon class and override the run() method
|
if pid > 0:
|
||||||
|
# exit first parent
|
||||||
|
sys.exit(0)
|
||||||
|
except OSError as e:
|
||||||
|
sys.stderr.write("fork #1 failed: %d (%s)\n" %
|
||||||
|
(e.errno, e.strerror))
|
||||||
|
log.error(e)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# decouple from parent environment
|
||||||
|
os.chdir("/")
|
||||||
|
os.setsid()
|
||||||
|
os.umask(0)
|
||||||
|
|
||||||
|
# do second fork
|
||||||
|
try:
|
||||||
|
pid = os.fork()
|
||||||
|
if pid > 0:
|
||||||
|
# exit from second parent
|
||||||
|
sys.exit(0)
|
||||||
|
except OSError as e:
|
||||||
|
sys.stderr.write("fork #2 failed: %d (%s)\n"
|
||||||
|
% (e.errno, e.strerror))
|
||||||
|
log.error(e)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# redirect standard file descriptors
|
||||||
|
sys.stdout.flush()
|
||||||
|
sys.stderr.flush()
|
||||||
|
si = file(self.stdin, 'r')
|
||||||
|
so = file(self.stdout, 'a+')
|
||||||
|
se = file(self.stderr, 'a+', 0)
|
||||||
|
os.dup2(si.fileno(), sys.stdin.fileno())
|
||||||
|
os.dup2(so.fileno(), sys.stdout.fileno())
|
||||||
|
os.dup2(se.fileno(), sys.stderr.fileno())
|
||||||
|
|
||||||
|
# write pidfile
|
||||||
|
atexit.register(self.delpid)
|
||||||
|
|
||||||
|
pid = str(os.getpid())
|
||||||
|
f = file(self.pidfile, 'w+')
|
||||||
|
f.write("%s\n" % pid)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
def delpid(self):
|
||||||
|
"""Delete PID file."""
|
||||||
|
os.remove(self.pidfile)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
"""Start the daemon."""
|
||||||
|
log.error("Test")
|
||||||
|
# Check for a pidfile to see if the daemon already runs
|
||||||
|
try:
|
||||||
|
pf = file(self.pidfile, 'r')
|
||||||
|
pid = int(pf.read().strip())
|
||||||
|
pf.close()
|
||||||
|
except IOError:
|
||||||
|
pid = None
|
||||||
|
|
||||||
|
if pid:
|
||||||
|
message = "pidfile %s already exist. Daemon" \
|
||||||
|
" already running?\n"
|
||||||
|
sys.stderr.write(message % self.pidfile)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Start the daemon
|
||||||
|
self.daemonize()
|
||||||
|
self.run()
|
||||||
|
|
||||||
|
# @todo needs some enhancement like check /proc/%pid/status if it's
|
||||||
|
# really running or not ! may be it's killed by external process
|
||||||
|
# the PID won't be updated !
|
||||||
|
def status(self):
|
||||||
|
"""Check daemon status."""
|
||||||
|
try:
|
||||||
|
pf = file(self.pidfile, 'r')
|
||||||
|
pid = int(pf.read().strip())
|
||||||
|
pf.close()
|
||||||
|
except IOError:
|
||||||
|
pid = None
|
||||||
|
|
||||||
|
if pid:
|
||||||
|
message = "pidfile %s already exist. Daemon already " \
|
||||||
|
"running. PID: %d \n"
|
||||||
|
sys.stdout.write(message % (self.pidfile, pid))
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
message = "Service not running!\n"
|
||||||
|
sys.stdout.write(message)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
"""Stop the daemon."""
|
||||||
|
# Get the pid from the pidfile
|
||||||
|
try:
|
||||||
|
pf = file(self.pidfile, 'r')
|
||||||
|
pid = int(pf.read().strip())
|
||||||
|
pf.close()
|
||||||
|
except IOError:
|
||||||
|
pid = None
|
||||||
|
|
||||||
|
if not pid:
|
||||||
|
message = "pidfile %s does not exist." \
|
||||||
|
" Daemon not running?\n"
|
||||||
|
sys.stderr.write(message % self.pidfile)
|
||||||
|
return # not an error in a restart
|
||||||
|
|
||||||
|
# Try killing the daemon process
|
||||||
|
try:
|
||||||
|
while 1:
|
||||||
|
os.kill(pid, SIGTERM)
|
||||||
|
time.sleep(0.1)
|
||||||
|
except OSError as err:
|
||||||
|
err = str(err)
|
||||||
|
if err.find("No such process") > 0:
|
||||||
|
if os.path.exists(self.pidfile):
|
||||||
|
os.remove(self.pidfile)
|
||||||
|
else:
|
||||||
|
print(str(err))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def restart(self):
|
||||||
|
"""Restart the daemon."""
|
||||||
|
self.stop()
|
||||||
|
self.start()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
"""You should override this method when you subclass Daemon.
|
||||||
|
|
||||||
|
It will be called after the process has been
|
||||||
|
daemonized by start() or restart().
|
||||||
"""
|
"""
|
||||||
def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null',
|
|
||||||
stderr='/dev/null'):
|
|
||||||
self.stdin = stdin
|
|
||||||
self.stdout = stdout
|
|
||||||
self.stderr = stderr
|
|
||||||
self.pidfile = pidfile
|
|
||||||
|
|
||||||
def daemonize(self):
|
|
||||||
"""
|
|
||||||
do the UNIX double-fork magic, see Stevens' "Advanced
|
|
||||||
Programming in the UNIX Environment" for details
|
|
||||||
(ISBN 0201563177)
|
|
||||||
http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
pid = os.fork()
|
|
||||||
if pid > 0:
|
|
||||||
# exit first parent
|
|
||||||
sys.exit(0)
|
|
||||||
except OSError, e:
|
|
||||||
sys.stderr.write("fork #1 failed: %d (%s)\n" %
|
|
||||||
(e.errno, e.strerror))
|
|
||||||
log.error(e)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# decouple from parent environment
|
|
||||||
os.chdir("/")
|
|
||||||
os.setsid()
|
|
||||||
os.umask(0)
|
|
||||||
|
|
||||||
# do second fork
|
|
||||||
try:
|
|
||||||
pid = os.fork()
|
|
||||||
if pid > 0:
|
|
||||||
# exit from second parent
|
|
||||||
sys.exit(0)
|
|
||||||
except OSError, e:
|
|
||||||
sys.stderr.write("fork #2 failed: %d (%s)\n"
|
|
||||||
% (e.errno, e.strerror))
|
|
||||||
log.error(e)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# redirect standard file descriptors
|
|
||||||
sys.stdout.flush()
|
|
||||||
sys.stderr.flush()
|
|
||||||
si = file(self.stdin, 'r')
|
|
||||||
so = file(self.stdout, 'a+')
|
|
||||||
se = file(self.stderr, 'a+', 0)
|
|
||||||
os.dup2(si.fileno(), sys.stdin.fileno())
|
|
||||||
os.dup2(so.fileno(), sys.stdout.fileno())
|
|
||||||
os.dup2(se.fileno(), sys.stderr.fileno())
|
|
||||||
|
|
||||||
# write pidfile
|
|
||||||
atexit.register(self.delpid)
|
|
||||||
|
|
||||||
pid = str(os.getpid())
|
|
||||||
f = file(self.pidfile, 'w+')
|
|
||||||
f.write("%s\n" % pid)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
def delpid(self):
|
|
||||||
os.remove(self.pidfile)
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
"""
|
|
||||||
Start the daemon
|
|
||||||
"""
|
|
||||||
log.error("Test")
|
|
||||||
# Check for a pidfile to see if the daemon already runs
|
|
||||||
try:
|
|
||||||
pf = file(self.pidfile,'r')
|
|
||||||
pid = int(pf.read().strip())
|
|
||||||
pf.close()
|
|
||||||
except IOError as e:
|
|
||||||
pid = None
|
|
||||||
|
|
||||||
if pid:
|
|
||||||
message = "pidfile %s already exist. Daemon" \
|
|
||||||
" already running?\n"
|
|
||||||
sys.stderr.write(message % self.pidfile)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Start the daemon
|
|
||||||
self.daemonize()
|
|
||||||
self.run()
|
|
||||||
|
|
||||||
# @todo needs some enhancement like check /proc/%pid/status if it's
|
|
||||||
# really running or not ! may be it's killed by external process
|
|
||||||
# the PID won't be updated !
|
|
||||||
def status(self):
|
|
||||||
try:
|
|
||||||
pf = file(self.pidfile, 'r')
|
|
||||||
pid = int(pf.read().strip())
|
|
||||||
pf.close()
|
|
||||||
except IOError as e:
|
|
||||||
pid = None
|
|
||||||
|
|
||||||
if pid:
|
|
||||||
message = "pidfile %s already exist. Daemon already " \
|
|
||||||
"running. PID: %d \n"
|
|
||||||
sys.stdout.write(message % (self.pidfile, pid))
|
|
||||||
sys.exit(0)
|
|
||||||
else:
|
|
||||||
message = "Service not running !\n"
|
|
||||||
sys.stdout.write(message)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
"""
|
|
||||||
Stop the daemon
|
|
||||||
"""
|
|
||||||
# Get the pid from the pidfile
|
|
||||||
try:
|
|
||||||
pf = file(self.pidfile,'r')
|
|
||||||
pid = int(pf.read().strip())
|
|
||||||
pf.close()
|
|
||||||
except IOError:
|
|
||||||
pid = None
|
|
||||||
|
|
||||||
if not pid:
|
|
||||||
message = "pidfile %s does not exist." \
|
|
||||||
" Daemon not running?\n"
|
|
||||||
sys.stderr.write(message % self.pidfile)
|
|
||||||
return # not an error in a restart
|
|
||||||
|
|
||||||
# Try killing the daemon process
|
|
||||||
try:
|
|
||||||
while 1:
|
|
||||||
os.kill(pid, SIGTERM)
|
|
||||||
time.sleep(0.1)
|
|
||||||
except OSError, err:
|
|
||||||
err = str(err)
|
|
||||||
if err.find("No such process") > 0:
|
|
||||||
if os.path.exists(self.pidfile):
|
|
||||||
os.remove(self.pidfile)
|
|
||||||
else:
|
|
||||||
print str(err)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def restart(self):
|
|
||||||
"""
|
|
||||||
Restart the daemon
|
|
||||||
"""
|
|
||||||
self.stop()
|
|
||||||
self.start()
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
"""
|
|
||||||
You should override this method when you subclass Daemon.
|
|
||||||
It will be called after the process has been
|
|
||||||
daemonized by start() or restart().
|
|
||||||
"""
|
|
|
@ -1,4 +1,5 @@
|
||||||
# (c) Copyright 2014,2015 Hewlett-Packard Development Company, L.P.
|
"""OpenStack client class."""
|
||||||
|
# (c) Copyright 2016 Hewlett-Packard Development Company, L.P.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
@ -11,21 +12,30 @@
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from keystoneclient import session
|
||||||
|
|
||||||
from keystoneclient.auth.identity import v3
|
from keystoneclient.auth.identity import v3
|
||||||
from keystoneclient import session
|
|
||||||
from novaclient.v2 import client as novaclient
|
|
||||||
from neutronclient.v2_0 import client as neutronclient
|
|
||||||
from keystoneclient.v3 import client as keystoneclient
|
from keystoneclient.v3 import client as keystoneclient
|
||||||
|
|
||||||
|
from neutronclient.v2_0 import client as neutronclient
|
||||||
|
|
||||||
|
from novaclient.v2 import client as novaclient
|
||||||
|
|
||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
|
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class OSClient:
|
class OSClient:
|
||||||
|
"""Provide OpenStack credentials to initalize the connection."""
|
||||||
|
|
||||||
def __init__(self, authurl, authmethod='password', ** kwargs):
|
def __init__(self, authurl, authmethod='password', ** kwargs):
|
||||||
"""
|
"""Initialize the all class vars.
|
||||||
Provide Openstack credentials to initalize the connection to Openstack
|
|
||||||
:param authmethod: string authmethod should be password or token but
|
:param authmethod: string authmethod should be password or token but
|
||||||
currently we support only password !
|
currently we support only password !
|
||||||
:param kwargs: username, user_id, project_name, project_id,
|
:param kwargs: username, user_id, project_name, project_id,
|
||||||
|
@ -49,15 +59,17 @@ class OSClient:
|
||||||
# self.user_id = kwargs.get('user_id', None)
|
# self.user_id = kwargs.get('user_id', None)
|
||||||
# self.user_domain_id = kwargs.get('user_domain_id', None)
|
# self.user_domain_id = kwargs.get('user_domain_id', None)
|
||||||
# self.user_domain_name = kwargs.get('user_domain_name', None)
|
# self.user_domain_name = kwargs.get('user_domain_name', None)
|
||||||
# self.project_domain_name = kwargs.get('project_domain_name', None)
|
# self.project_domain_name =
|
||||||
|
# kwargs.get('project_domain_name', None)
|
||||||
# self.endpoint_type = kwargs.get('endpoint_type', 'internalURL')
|
# self.endpoint_type = kwargs.get('endpoint_type', 'internalURL')
|
||||||
else:
|
else:
|
||||||
print "The available authmethod is password for the time being" \
|
print("The available authmethod is password for the time being")
|
||||||
"Please, provide a password credentials :) "
|
print("Please, provide a password credential.")
|
||||||
|
|
||||||
self.auth()
|
self.auth()
|
||||||
|
|
||||||
def auth(self):
|
def auth(self):
|
||||||
|
"""Create a session."""
|
||||||
auth = v3.Password(auth_url=self.authurl,
|
auth = v3.Password(auth_url=self.authurl,
|
||||||
**self.kwargs)
|
**self.kwargs)
|
||||||
self.auth_session = session.Session(auth=auth)
|
self.auth_session = session.Session(auth=auth)
|
||||||
|
@ -89,16 +101,16 @@ class OSClient:
|
||||||
def neutronagents(self, hosts=[]):
|
def neutronagents(self, hosts=[]):
|
||||||
if not hosts:
|
if not hosts:
|
||||||
hosts = self.compute_hosts
|
hosts = self.compute_hosts
|
||||||
new_sess = session.Session(auth=self.auth_session.auth)
|
auth_session = session.Session(auth=self.auth_session.auth)
|
||||||
neutron = neutronclient.Client(session=new_sess,
|
neutron = neutronclient.Client(session=auth_session,
|
||||||
endpoint_type=self.endpoint_type)
|
endpoint_type=self.endpoint_type)
|
||||||
self.auth_session = new_sess
|
self.auth_session = auth_session
|
||||||
agents = neutron.list_agents()
|
agents = neutron.list_agents()
|
||||||
neutron_agents = []
|
neutron_agents = []
|
||||||
for agent in agents.get('agents'):
|
for agent in agents.get('agents'):
|
||||||
if agent.get('host') in hosts and agent.get('binary') == \
|
if agent.get('host') in hosts and agent.get('binary') == \
|
||||||
'neutron-openvswitch-agent':
|
'neutron-openvswitch-agent':
|
||||||
neutron_agents.append(agent)
|
neutron_agents.append(agent)
|
||||||
|
|
||||||
return neutron_agents
|
return neutron_agents
|
||||||
|
|
||||||
|
@ -109,10 +121,10 @@ class OSClient:
|
||||||
:param nodes: List of nodes to be evacuated !
|
:param nodes: List of nodes to be evacuated !
|
||||||
:return: List of nodes with VMs that were running on that node
|
:return: List of nodes with VMs that were running on that node
|
||||||
"""
|
"""
|
||||||
new_sess = session.Session(auth=self.auth_session.auth)
|
auth_session = session.Session(auth=self.auth_session.auth)
|
||||||
nova = novaclient.Client(session=new_sess,
|
nova = novaclient.Client(session=auth_session,
|
||||||
endpoint_type=self.endpoint_type)
|
endpoint_type=self.endpoint_type)
|
||||||
self.auth_session = new_sess
|
self.auth_session = auth_session
|
||||||
evacuated_nodes = []
|
evacuated_nodes = []
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
hypervisors = nova.hypervisors.search(node.get('host'), True)
|
hypervisors = nova.hypervisors.search(node.get('host'), True)
|
||||||
|
@ -125,15 +137,17 @@ class OSClient:
|
||||||
on_shared_storage=True)
|
on_shared_storage=True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.error(e)
|
LOG.error(e)
|
||||||
host = {'host': node.get('host'), 'servers': hypervisor.servers}
|
host = {'host': node.get(
|
||||||
|
'host'), 'servers': hypervisor.servers}
|
||||||
evacuated_nodes.append(host)
|
evacuated_nodes.append(host)
|
||||||
return evacuated_nodes
|
return evacuated_nodes
|
||||||
|
|
||||||
def set_in_maintance(self, nodes):
|
def set_in_maintenance(self, nodes):
|
||||||
new_sess = session.Session(auth=self.auth_session.auth)
|
"""Set compute nodes in maintenance mode."""
|
||||||
nova = novaclient.Client(session=new_sess,
|
auth_session = session.Session(auth=self.auth_session.auth)
|
||||||
|
nova = novaclient.Client(session=auth_session,
|
||||||
endpoint_type=self.endpoint_type)
|
endpoint_type=self.endpoint_type)
|
||||||
self.auth_session = new_sess
|
self.auth_session = auth_session
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
output = []
|
output = []
|
||||||
host = nova.hosts.get(node)[0]
|
host = nova.hosts.get(node)[0]
|
||||||
|
@ -145,12 +159,13 @@ class OSClient:
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def get_session(self):
|
def get_session(self):
|
||||||
|
"""Get the authentication section."""
|
||||||
auth_session = session.Session(auth=self.auth_session.auth)
|
auth_session = session.Session(auth=self.auth_session.auth)
|
||||||
return auth_session
|
return auth_session
|
||||||
|
|
||||||
def get_node_status(self, node):
|
def get_node_status(self, node):
|
||||||
"""
|
"""Check the node nova-service status and if it's disabled or not.
|
||||||
Check the node nova-service status and if it's disabled or not
|
|
||||||
:param node: dict contains node info
|
:param node: dict contains node info
|
||||||
:return: True or False. True => node disabled, False => node is enabled
|
:return: True or False. True => node disabled, False => node is enabled
|
||||||
or unknow status !
|
or unknow status !
|
||||||
|
@ -172,6 +187,7 @@ class OSClient:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def disable_node(self, node):
|
def disable_node(self, node):
|
||||||
|
"""Disable nova on the failing node."""
|
||||||
auth_session = session.Session(auth=self.auth_session.auth)
|
auth_session = session.Session(auth=self.auth_session.auth)
|
||||||
nova = novaclient.Client(session=auth_session,
|
nova = novaclient.Client(session=auth_session,
|
||||||
endpoint_type=self.endpoint_type)
|
endpoint_type=self.endpoint_type)
|
||||||
|
@ -189,7 +205,7 @@ class OSClient:
|
||||||
nova.services.disable_log_reason(
|
nova.services.disable_log_reason(
|
||||||
host=node.get('host'),
|
host=node.get('host'),
|
||||||
binary=node.get('binary'),
|
binary=node.get('binary'),
|
||||||
reason='Host Failed and needs to be evacuated.'
|
reason='Host failed and needs to be evacuated.'
|
||||||
)
|
)
|
||||||
del nova
|
del nova
|
||||||
LOG.info('Compute host: %s has been disabled to be evacuated. '
|
LOG.info('Compute host: %s has been disabled to be evacuated. '
|
||||||
|
@ -200,6 +216,7 @@ class OSClient:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_hypervisor_instances(self, node):
|
def get_hypervisor_instances(self, node):
|
||||||
|
"""Get instances from an hypervisor."""
|
||||||
auth_session = session.Session(auth=self.auth_session.auth)
|
auth_session = session.Session(auth=self.auth_session.auth)
|
||||||
nova = novaclient.Client(session=auth_session,
|
nova = novaclient.Client(session=auth_session,
|
||||||
endpoint_type=self.endpoint_type)
|
endpoint_type=self.endpoint_type)
|
||||||
|
@ -209,8 +226,8 @@ class OSClient:
|
||||||
return hypervisors[0].servers
|
return hypervisors[0].servers
|
||||||
|
|
||||||
def get_hypervisor(self, node):
|
def get_hypervisor(self, node):
|
||||||
"""
|
"""Get an instance of the hypervisor.
|
||||||
Get an instance of the hypervisor, so you can do any operation you want.
|
|
||||||
:param node: dict contains host index
|
:param node: dict contains host index
|
||||||
:return: Hypervisor
|
:return: Hypervisor
|
||||||
"""
|
"""
|
||||||
|
@ -223,6 +240,7 @@ class OSClient:
|
||||||
return hypervisors[0]
|
return hypervisors[0]
|
||||||
|
|
||||||
def get_instances_list(self, node):
|
def get_instances_list(self, node):
|
||||||
|
"""Get instances running on a node for all tenants."""
|
||||||
auth_session = session.Session(auth=self.auth_session.auth)
|
auth_session = session.Session(auth=self.auth_session.auth)
|
||||||
nova = novaclient.Client(session=auth_session,
|
nova = novaclient.Client(session=auth_session,
|
||||||
endpoint_type=self.endpoint_type)
|
endpoint_type=self.endpoint_type)
|
||||||
|
@ -239,6 +257,7 @@ class OSClient:
|
||||||
return self.get_instances_list(node)
|
return self.get_instances_list(node)
|
||||||
|
|
||||||
def list_tenants(self):
|
def list_tenants(self):
|
||||||
|
"""List tenants."""
|
||||||
auth_session = session.Session(auth=self.auth_session.auth)
|
auth_session = session.Session(auth=self.auth_session.auth)
|
||||||
keystone = keystoneclient.Client(session=auth_session,
|
keystone = keystoneclient.Client(session=auth_session,
|
||||||
endpoint_type=self.endpoint_type)
|
endpoint_type=self.endpoint_type)
|
||||||
|
@ -251,6 +270,7 @@ class OSClient:
|
||||||
return projects_data
|
return projects_data
|
||||||
|
|
||||||
def users_on_tenant(self, tenant):
|
def users_on_tenant(self, tenant):
|
||||||
|
"""List user per project."""
|
||||||
auth_session = session.Session(auth=self.auth_session.auth)
|
auth_session = session.Session(auth=self.auth_session.auth)
|
||||||
keystone = keystoneclient.Client(session=auth_session,
|
keystone = keystoneclient.Client(session=auth_session,
|
||||||
endpoint_type=self.endpoint_type,
|
endpoint_type=self.endpoint_type,
|
||||||
|
@ -259,7 +279,7 @@ class OSClient:
|
||||||
try:
|
try:
|
||||||
users = keystone.users.list(default_project=tenant)
|
users = keystone.users.list(default_project=tenant)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print e
|
print(e)
|
||||||
users_list = []
|
users_list = []
|
||||||
for user in users:
|
for user in users:
|
||||||
users_list.append(user.to_dict())
|
users_list.append(user.to_dict())
|
||||||
|
@ -267,6 +287,7 @@ class OSClient:
|
||||||
return users_list
|
return users_list
|
||||||
|
|
||||||
def get_hypervisors_stats(self):
|
def get_hypervisors_stats(self):
|
||||||
|
"""Get stats for all hypervisors."""
|
||||||
auth_session = session.Session(auth=self.auth_session.auth)
|
auth_session = session.Session(auth=self.auth_session.auth)
|
||||||
nova = novaclient.Client(session=auth_session,
|
nova = novaclient.Client(session=auth_session,
|
||||||
endpoint_type=self.endpoint_type)
|
endpoint_type=self.endpoint_type)
|
||||||
|
@ -274,6 +295,7 @@ class OSClient:
|
||||||
return stats.to_dict()
|
return stats.to_dict()
|
||||||
|
|
||||||
def get_hypervisor_details(self, node):
|
def get_hypervisor_details(self, node):
|
||||||
|
"""Get details about hypervisor running on the provided node."""
|
||||||
auth_session = session.Session(auth=self.auth_session.auth)
|
auth_session = session.Session(auth=self.auth_session.auth)
|
||||||
nova = novaclient.Client(session=auth_session,
|
nova = novaclient.Client(session=auth_session,
|
||||||
endpoint_type=self.endpoint_type)
|
endpoint_type=self.endpoint_type)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# (c) Copyright 2014,2015 Hewlett-Packard Development Company, L.P.
|
"""Utility functions shared from all modules into the project."""
|
||||||
|
# (c) Copyright 2016 Hewlett-Packard Development Company, L.P.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
@ -11,18 +12,22 @@
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from osha.common.osclient import OSClient
|
|
||||||
|
import jinja2
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
import jinja2
|
|
||||||
|
from osha.common.osclient import OSClient
|
||||||
|
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def env(*env_vars, **kwargs):
|
def env(*env_vars, **kwargs):
|
||||||
|
"""Get all environment variables."""
|
||||||
for variable in env_vars:
|
for variable in env_vars:
|
||||||
value = os.environ.get(variable, None)
|
value = os.environ.get(variable, None)
|
||||||
if value:
|
if value:
|
||||||
|
@ -31,7 +36,8 @@ def env(*env_vars, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
def get_os_client():
|
def get_os_client():
|
||||||
"""
|
"""Return the OpenStack client.
|
||||||
|
|
||||||
Loads credentials from [keystone_authtoken] section in the configuration
|
Loads credentials from [keystone_authtoken] section in the configuration
|
||||||
file and initialize the client and return an instance of the client
|
file and initialize the client and return an instance of the client
|
||||||
:return: Initialized instance of OS Client
|
:return: Initialized instance of OS Client
|
||||||
|
@ -53,14 +59,15 @@ def get_os_client():
|
||||||
|
|
||||||
|
|
||||||
def load_jinja_templates(template_dir, template_name, template_vars):
|
def load_jinja_templates(template_dir, template_name, template_vars):
|
||||||
"""
|
"""Load and render existing Jinja2 templates.
|
||||||
Load and render existing Jinja2 templates. The main purpose of the function
|
|
||||||
is to prepare the message to be sent and render it for the driver to send
|
The main purpose of the function is to prepare the message to be sent and
|
||||||
it directly
|
render it for the driver to send it directly.
|
||||||
|
|
||||||
:param template_dir: Location where jinja2 templates are stored
|
:param template_dir: Location where jinja2 templates are stored
|
||||||
:param template_name: name of the template to load it
|
:param template_name: name of the template to load it
|
||||||
:param template_vars: Dict to replace existing vars in the template with
|
:param template_vars: Dict to replace existing vars in the template with
|
||||||
values.
|
values.
|
||||||
:return: String message
|
:return: String message
|
||||||
"""
|
"""
|
||||||
template_loader = jinja2.FileSystemLoader(searchpath=template_dir)
|
template_loader = jinja2.FileSystemLoader(searchpath=template_dir)
|
||||||
|
@ -70,7 +77,8 @@ def load_jinja_templates(template_dir, template_name, template_vars):
|
||||||
|
|
||||||
|
|
||||||
def get_admin_os_client():
|
def get_admin_os_client():
|
||||||
"""
|
"""Return admin client data.
|
||||||
|
|
||||||
Loads credentials from [keystone_authtoken] section in the configuration
|
Loads credentials from [keystone_authtoken] section in the configuration
|
||||||
file and initialize the client with admin privileges and return
|
file and initialize the client with admin privileges and return
|
||||||
an instance of the client
|
an instance of the client
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# (c) Copyright 2014,2015 Hewlett-Packard Development Company, L.P.
|
# (c) Copyright 2016 Hewlett-Packard Development Company, L.P.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
@ -12,52 +12,58 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
"""Abstract fencer"""
|
||||||
|
|
||||||
import abc
|
import abc
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(abc.ABCMeta)
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
class FencerBaseDriver(object):
|
class FencerBaseDriver(object):
|
||||||
"""
|
|
||||||
Abstract class that all fencer plugins should implement to have a
|
"""Abstract class that all fencer plugins.
|
||||||
unified interface and as many plugins as we want...
|
|
||||||
|
Should be implemented to have a unified interface and as many plugins as
|
||||||
|
needed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, node, **kwargs):
|
def __init__(self, node, **kwargs):
|
||||||
"""
|
"""Initialize the driver.
|
||||||
Initializing the driver. Any fencer driver requires the following
|
|
||||||
parameters to do the api calls. All these parameters can be passed from
|
Any fencer driver requires the following parameters to do the api
|
||||||
the configuration file in /etc/osha/osha.conf (default)
|
calls. All these parameters can be passed from the configuration
|
||||||
|
file in /etc/osha/osha.conf (default).
|
||||||
|
|
||||||
:param node: dict with all node details. (/etc/osha/servers.yml) ?
|
:param node: dict with all node details. (/etc/osha/servers.yml) ?
|
||||||
:param kwargs: any additional parameters can be passed using this config
|
:param kwargs: any additional parameters can be passed using this
|
||||||
option.
|
config option.
|
||||||
"""
|
"""
|
||||||
self.node = node
|
self.node = node
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def graceful_shutdown(self):
|
def graceful_shutdown(self):
|
||||||
"""
|
"""Gracefully shutdown the compute node to evacuate it."""
|
||||||
Gracefully shutdown the compute node to evacuate it.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def force_shutdown(self):
|
def force_shutdown(self):
|
||||||
"""
|
"""Force shutdown the compute node to evacuate it.
|
||||||
Force shutdown the compute node to evacuate it. May be you can try force
|
|
||||||
shutdown if the graceful shutdown failed
|
May be you can try force shutdown if the graceful shutdown failed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def status(self):
|
def status(self):
|
||||||
"""
|
"""Get compute node status.
|
||||||
Get compute node status. should return 1 if on and 0 if off or
|
|
||||||
-1 if error or unknown power status
|
Should return 1 if on and 0 if off or -1 if error or unknown power
|
||||||
|
status.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def get_info(self):
|
def get_info(self):
|
||||||
"""
|
"""Get Driver information.
|
||||||
Get Driver information ..
|
|
||||||
:return: dict of name, version, author, ...
|
:return: dict of name, version, author, ...
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue