diff --git a/defaults/main.yml b/defaults/main.yml index 82258b9f..bdeb97f3 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -45,10 +45,6 @@ neutron_install_method: "source" ### Python code details ### -# Neutron logs are collected with systemd-journald by default -# neutron_log_dir may be used for complience with old ha-tool -#neutron_log_dir: "/var/log/neutron" - # Set the package install state for pip_package # Options are 'present' and 'latest' neutron_pip_package_state: "latest" @@ -125,7 +121,7 @@ neutron_dns_domain: "openstacklocal." # Dnsmasq doesn't work with config_template override, a deployer # should instead configure its own neutron_dhcp_config key/values like this: #neutron_dhcp_config: -# log-facility: "{{ neutron_log_dir }}/neutron-dnsmasq.log" +# dhcp-option-force: "26,1500" neutron_dhcp_config: {} # Disable dnsmasq to resolve DNS via local resolv.conf. @@ -383,13 +379,6 @@ neutron_local_ip: 127.0.0.1 ### L3 Agent Plugin Configuration ### -# Set this option to "true" to enable legacy neutron L3HA tool support -# This tool is useful to ensure any non-HA neutron entities -# are re-scheduled if the agent managing them goes down. -# It is also useful if the built-in HA capabilities cannot -# be used in the environment for whatever reason. -neutron_legacy_ha_tool_enabled: false - # L3HA configuration options neutron_ha_vrrp_auth_type: PASS neutron_l3_ha_net_cidr: 169.254.192.0/18 diff --git a/releasenotes/notes/drop_legacy_l3_ha-e8d5d3dbd7c882fc.yaml b/releasenotes/notes/drop_legacy_l3_ha-e8d5d3dbd7c882fc.yaml new file mode 100644 index 00000000..c31b9b96 --- /dev/null +++ b/releasenotes/notes/drop_legacy_l3_ha-e8d5d3dbd7c882fc.yaml @@ -0,0 +1,5 @@ +--- +deprecations: + - | + Support of the legacy neutron L3 tool has been dropped. Deployers are + appreciated to use built-in l3-agent options for configuring HA. diff --git a/tasks/main.yml b/tasks/main.yml index b617bb8d..d7e78a8c 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -168,11 +168,5 @@ tags: - neutron-config -- import_tasks: neutron_l3_ha.yml - when: - - "neutron_services['neutron-l3-agent']['group'] in group_names" - tags: - - neutron-config - - name: Flush handlers meta: flush_handlers diff --git a/tasks/neutron_l3_ha.yml b/tasks/neutron_l3_ha.yml deleted file mode 100644 index b89580d5..00000000 --- a/tasks/neutron_l3_ha.yml +++ /dev/null @@ -1,71 +0,0 @@ ---- -# Copyright 2014, Rackspace US, 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. - -- name: Implement the legacy neutron L3HA tool scripts - when: - - neutron_legacy_ha_tool_enabled | bool - block: - - name: Implement the neutron HA tool script - template: - src: "neutron-ha-tool.py.j2" - dest: "/opt/neutron-ha-tool.py" - owner: "root" - group: "root" - mode: "0755" - - - name: Convert the hostname to an int - name2int: - name: "{{ inventory_hostname }}" - register: hashed_name - - # These are used in the Neutron HA Cron job script, and processed in the template. - - name: Creating Job Facts - set_fact: - do_job: ". /root/openrc && /opt/neutron-ha-tool.py {% if keystone_service_internaluri_insecure | bool %}--insecure {% endif %}--l3-agent-migrate" - sleep_time: "{{ hashed_name.int_value }}" - - - name: Implement openrc/clouds.yaml - include_role: - name: "openstack_openrc" - - - name: Implement the Neutron HA job script - template: - src: "neutron_ha_tool.sh.j2" - dest: "/opt/neutron-ha-tool.sh" - owner: "root" - group: "root" - mode: "0755" - -- name: Create Neutron HA - cron: - name: "neutron-ha-tool" - minute: "*/1" - day: "*" - hour: "*" - month: "*" - state: "{{ (neutron_legacy_ha_tool_enabled | bool) | ternary('present', 'absent') }}" - job: "/opt/neutron-ha-tool.sh" - user: root - cron_file: "neutron-ha-tool" - -- name: Remove AT&T neutron ha tool when disabled - file: - path: "{{ item }}" - state: "absent" - with_items: - - "/opt/neutron-ha-tool.py" - - "/opt/neutron-ha-tool.sh" - when: - - not neutron_legacy_ha_tool_enabled | bool diff --git a/tasks/neutron_pre_install.yml b/tasks/neutron_pre_install.yml index 264cd2b2..bc539e6c 100644 --- a/tasks/neutron_pre_install.yml +++ b/tasks/neutron_pre_install.yml @@ -87,24 +87,6 @@ mode: "0755" - path: "{{ neutron_system_home_folder }}/ha_confs" -- name: Create log directory - block: - - name: Test for log directory - stat: - path: "{{ neutron_log_dir }}" - register: log_dir - - name: Create neutron log dir - file: - path: "{{ item.path }}" - state: directory - owner: "{{ item.owner|default(neutron_system_user_name) }}" - group: "{{ item.group|default(neutron_system_group_name) }}" - mode: "{{ item.mode|default('0755') }}" - with_items: - - { path: "{{ neutron_log_dir }}" } - when: log_dir.stat.exists and file_details.stat.isdir - when: neutron_log_dir is defined - - name: Drop sudoers file template: src: "sudoers.j2" diff --git a/templates/neutron-ha-tool.py.j2 b/templates/neutron-ha-tool.py.j2 deleted file mode 100644 index 56fc09f7..00000000 --- a/templates/neutron-ha-tool.py.j2 +++ /dev/null @@ -1,622 +0,0 @@ -#!{{ neutron_bin }}/python - -# Copyright 2013 AT&T Services, Inc. -# All Rights Reserved. -# -# 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 argparse -from collections import OrderedDict -import logging -from logging import handlers -from logging.handlers import SysLogHandler -import os -import random -import sys -import time - -import keystoneclient.v3.client as kclientv3 -import keystoneclient.v2_0.client as kclientv2 -from neutronclient.neutron import client as nclient - -LOG_NAME = 'neutron-ha-tool' -LOG = logging.getLogger(LOG_NAME) -LOG_FORMAT = '%(asctime)s %(name)-12s %(levelname)-8s %(message)s' -LOG_DATE = '%m-%d %H:%M' -DESCRIPTION = "neutron High Availability Tool" -TAKEOVER_DELAY = int(random.random() * 30 + 30) - - -def load_local_logging(): - """Load a local logger for neutron ha tool. - - This method returns a logging object - - :returns: ``object`` - """ - - user = os.getuid() - home = os.path.expanduser('~') - log_dir = '{{ neutron_log_dir }}' - filename = '%s.log' % LOG_NAME - - if user == 0: - file_name = os.path.join(log_dir, filename) - elif os.stat(log_dir).st_uid == user: - file_name = os.path.join(log_dir, filename) - elif os.stat(log_dir).st_gid == user: - file_name = os.path.join(log_dir, filename) - else: - file_name = os.path.join(home, filename) - - log_format = logging.Formatter(fmt=LOG_FORMAT, datefmt=LOG_DATE) - - file_handler = handlers.RotatingFileHandler( - filename=file_name, - maxBytes=(500 * 1024 * 1024), - backupCount=5 - ) - file_handler.setLevel(logging.DEBUG) - file_handler.name = LOG_NAME - file_handler.setFormatter(log_format) - - log = logging.getLogger(LOG_NAME) - log.setLevel(logging.DEBUG) - log.addHandler(file_handler) - return log - - -IDENTITY_API_VERSIONS = { - '2.0': kclientv2, - '2': kclientv2, - '3': kclientv3 -} - - -def parse_args(): - - # ensure environment has necessary items to authenticate - for key in ['OS_USERNAME', 'OS_PASSWORD', 'OS_AUTH_URL', - 'OS_ENDPOINT_TYPE']: - if key not in os.environ.keys(): - raise SystemExit("Your environment is missing '%s'") - - ap = argparse.ArgumentParser(description=DESCRIPTION) - ap.add_argument('-d', '--debug', action='store_true', - default=False, help='Show debugging output') - ap.add_argument('-q', '--quiet', action='store_true', default=False, - help='Only show error and warning messages') - ap.add_argument('-n', '--noop', action='store_true', default=False, - help='Do not do any modifying operations (dry-run)') - ap.add_argument('--l3-agent-check', action='store_true', default=False, - help='Show routers associated with offline l3 agents') - ap.add_argument('--l3-agent-migrate', action='store_true', default=False, - help='Migrate routers away from offline l3 agents') - ap.add_argument('--l3-agent-rebalance', action='store_true', default=False, - help='Rebalance router count on all l3 agents') - ap.add_argument('--replicate-dhcp', action='store_true', default=False, - help='Replicate DHCP configuration to all agents') - ap.add_argument('--now', action='store_true', default=False, - help='Migrate Routers immediately without a delay.') - ap.add_argument('--insecure', action='store_true', default=False, - help='Explicitly allow neutron-ha-tool to perform ' - '"insecure" SSL (https) requests. The server\'s ' - 'certificate will not be verified against any ' - 'certificate authorities. This option should be used ' - 'with caution.') - return ap.parse_args() - - -def setup_logging(args): - level = logging.INFO - if args.quiet: - level = logging.WARN - if args.debug: - level = logging.DEBUG - logging.basicConfig(level=level, format=LOG_FORMAT, date_fmt=LOG_DATE) - handler = SysLogHandler(address='/dev/log') - syslog_formatter = logging.Formatter('%(name)s: %(levelname)s %(message)s') - handler.setFormatter(syslog_formatter) - LOG.addHandler(handler) - - # Create a local rotating logging object - load_local_logging() - - -def run(args): - try: - ca = os.environ['OS_CACERT'] - except KeyError: - ca = None - - auth_version = os.getenv('OS_AUTH_VERSION', None) - if not auth_version: - auth_version = os.getenv('OS_IDENTITY_API_VERSION', None) - if not auth_version: - auth_version = 3 - - kclient = IDENTITY_API_VERSIONS[auth_version] - kclient_kwargs = dict() - kclient_kwargs['username'] = os.environ['OS_USERNAME'] - kclient_kwargs['password'] = os.environ['OS_PASSWORD'] - kclient_kwargs['insecure'] = args.insecure - kclient_kwargs['ca_cert'] = ca - kclient_kwargs['auth_url'] = os.environ['OS_AUTH_URL'] - # Set the region if one is defined - if 'OS_REGION_NAME' in os.environ: - kclient_kwargs['region_name'] = os.environ['OS_REGION_NAME'] - - tenant_name = os.getenv('OS_TENANT_NAME') - if tenant_name and auth_version != 3: - kclient_kwargs['tenant_name'] = tenant_name - else: - kclient_kwargs['project_name'] = os.environ['OS_PROJECT_NAME'] - - # Instantiate Keystone client - keystone = kclient.Client(**kclient_kwargs) - - # Instantiate Neutron client - qclient = nclient.Client( - '2.0', - endpoint_url=keystone.service_catalog.url_for( - service_type='network', - endpoint_type=os.environ['OS_ENDPOINT_TYPE'] - ), - token=keystone.get_token(keystone.session) - ) - - # set json return type - qclient.format = 'json' - - if args.l3_agent_check: - LOG.info("Performing L3 Agent Health Check") - l3_agent_check(qclient) - - if args.l3_agent_migrate: - LOG.info("Performing L3 Agent Migration for Offline L3 Agents") - l3_agent_migrate(qclient, args.noop, args.now) - - if args.l3_agent_rebalance: - LOG.info("Rebalancing L3 Agent Router Count") - l3_agent_rebalance(qclient, args.noop) - - if args.replicate_dhcp: - LOG.info("Performing DHCP Replication of Networks to Agents") - replicate_dhcp(qclient, args.noop) - - -def l3_agent_rebalance(qclient, noop=False): - """Rebalance l3 agent router count across agents. - - The number of routers on each l3 agent will be as close as possible - which should help distribute load as new l3 agents come online. - - :param qclient: A neutronclient - :param noop: Optional noop flag - """ - - # {u'binary': u'neutron-l3-agent', - # u'description': None, - # u'admin_state_up': True, - # u'heartbeat_timestamp': u'2013-07-02 22:20:23', - # u'alive': True, - # u'topic': u'l3_agent', - # u'host': u'o3r3.int.san3.attcompute.com', - # u'agent_type': u'L3 agent', - # u'created_at': u'2013-07-02 14:50:58', - # u'started_at': u'2013-07-02 18:00:55', - # u'id': u'6efe494a-616c-41ea-9c8f-2c592f4d46ff', - # u'configurations': { - # u'router_id': u'', - # u'handle_internal_only_routers': True, - # u'use_namespaces': True, - # u'routers': 5, - # u'interfaces': 3, - # u'floating_ips': 9, - # u'interface_driver': - # u'neutron.agent.linux.interface.OVSInterfaceDriver', - # u'ex_gw_ports': 3} - # } - - l3_agent_dict = {} - agents = list_agents(qclient, agent_type='L3 agent') - num_agents = len(agents) - if num_agents <= 1: - LOG.info("No rebalancing required for 1 or fewer agents") - return - - for l3_agent in agents: - l3_agent_dict[l3_agent['id']] = \ - list_routers_on_l3_agent(qclient, l3_agent['id']) - - ordered_l3_agent_dict = OrderedDict(sorted(l3_agent_dict.items(), - key=lambda t: len(t[0]))) - ordered_l3_agent_list = list(ordered_l3_agent_dict) - num_agents = len(ordered_l3_agent_list) - LOG.info("Agent list: %s", - ordered_l3_agent_list[0:(num_agents - 1 / 2) + 1]) - i = 0 - for agent in ordered_l3_agent_list[0:num_agents - 1 / 2]: - low_agent_id = ordered_l3_agent_list[i] - hgh_agent_id = ordered_l3_agent_list[-(i + 1)] - - # do nothing if we end up comparing the same router - if low_agent_id == hgh_agent_id: - continue - - LOG.info("Examining low_agent=%s, high_agent=%s", - low_agent_id, hgh_agent_id) - - low_agent_router_count = len(l3_agent_dict[low_agent_id]) - hgh_agent_router_count = len(l3_agent_dict[hgh_agent_id]) - - LOG.info("Low Count=%s, High Count=%s", - low_agent_router_count, hgh_agent_router_count) - - for router_id in l3_agent_dict[hgh_agent_id]: - if low_agent_router_count >= hgh_agent_router_count: - break - else: - LOG.info("Migrating router=%s from agent=%s to agent=%s", - router_id, hgh_agent_id, low_agent_id) - try: - if not noop: - migrate_router(qclient, router_id, hgh_agent_id, - low_agent_id) - low_agent_router_count += 1 - hgh_agent_router_count -= 1 - except Exception: - LOG.exception("Failed to migrate router=%s from agent=%s " - "to agent=%s", router_id, hgh_agent_id, - low_agent_id) - continue - i += 1 - - -def l3_agent_check(qclient): - """Walk the l3 agents searching for agents that are offline. - - Show routers that are offline and where we would migrate them to. - - :param qclient: A neutronclient - - """ - - migration_count = 0 - agent_list = list_agents(qclient) - agent_dead_list = agent_dead_id_list(agent_list, 'L3 agent') - agent_alive_list = agent_alive_id_list(agent_list, 'L3 agent') - LOG.info("There are %s offline L3 agents and %s online L3 agents", - len(agent_dead_list), len(agent_alive_list)) - - if len(agent_dead_list) > 0: - for agent_id in agent_dead_list: - LOG.info("Querying agent_id=%s for routers to migrate", agent_id) - router_id_list = list_routers_on_l3_agent(qclient, agent_id) - - for router_id in router_id_list: - try: - target_id = random.choice(agent_alive_list) - except IndexError: - LOG.warning("There are no l3 agents alive we could " - "migrate routers onto.") - target_id = None - - migration_count += 1 - LOG.warning("Would like to migrate router=%s to agent=%s", - router_id, target_id) - - if migration_count > 0: - sys.exit(2) - - -def l3_agent_migrate(qclient, noop=False, now=False): - """Walk the l3 agents searching for agents that are offline. - - For those that are offline, we will retrieve a list of routers on - them and migrate them to a random l3 agent that is online. - - :param qclient: A neutronclient - :param noop: Optional noop flag - :param now: Optional. If false (the default), we'll wait for a random - amount of time (between 30 and 60 seconds) before migration. If - true, routers are migrated immediately. - - """ - - migration_count = 0 - agent_list = list_agents(qclient) - agent_dead_list = agent_dead_id_list(agent_list, 'L3 agent') - agent_alive_list = agent_alive_id_list(agent_list, 'L3 agent') - LOG.info("There are %s offline L3 agents and %s online L3 agents", - len(agent_dead_list), len(agent_alive_list)) - - if len(agent_dead_list) > 0: - if len(agent_alive_list) < 1: - LOG.exception("There are no l3 agents alive to migrate " - "routers onto") - - timeout = 0 - if not now: - while timeout < TAKEOVER_DELAY: - - agent_list_new = list_agents(qclient) - agent_dead_list_new = agent_dead_id_list(agent_list_new, - 'L3 agent') - if len(agent_dead_list_new) < len(agent_dead_list): - LOG.info("Skipping router failover since an agent came " - "online while ensuring agents offline for %s " - "seconds", TAKEOVER_DELAY) - sys.exit(0) - - LOG.info("Agent found offline for seconds=%s but waiting " - "seconds=%s before migration", - timeout, TAKEOVER_DELAY) - timeout += 1 - time.sleep(1) - - for agent_id in agent_dead_list: - LOG.info("Querying agent_id=%s for routers to migrate", agent_id) - router_id_list = list_routers_on_l3_agent(qclient, agent_id) - - for router_id in router_id_list: - - target_id = random.choice(agent_alive_list) - LOG.info("Migrating router=%s to agent=%s", - router_id, target_id) - - try: - if not noop: - migrate_router(qclient, router_id, agent_id, target_id) - migration_count += 1 - except Exception: - LOG.exception("There was an error migrating a router") - continue - - LOG.info("%s routers required migration from offline L3 agents", - migration_count) - - -def replicate_dhcp(qclient, noop=False): - """Retrieve a network list and then probe each DHCP agent - - This will ensure they have that network assigned. - - :param qclient: A neutronclient - :param noop: Optional noop flag - - """ - - added = 0 - networks = list_networks(qclient) - network_id_list = [n['id'] for n in networks] - agents = list_agents(qclient, agent_type='DHCP agent') - LOG.info("Replicating %s networks to %s DHCP agents", len(networks), - len(agents)) - for dhcp_agent_id in [a['id'] for a in agents]: - networks_on_agent = \ - qclient.list_networks_on_dhcp_agent(dhcp_agent_id)['networks'] - network_id_on_agent = [n['id'] for n in networks_on_agent] - for network_id in network_id_list: - if network_id not in network_id_on_agent: - try: - dhcp_body = {'network_id': network_id} - if not noop: - qclient.add_network_to_dhcp_agent(dhcp_agent_id, - dhcp_body) - LOG.info("Added missing network=%s to dhcp agent=%s", - network_id, dhcp_agent_id) - added += 1 - except Exception: - LOG.exception("Failed to add network_id=%s to" - "dhcp_agent=%s", network_id, dhcp_agent_id) - continue - - LOG.info("Added %s networks to DHCP agents", added) - - -def migrate_router(qclient, router_id, agent_id, target_id): - """Returns nothing, and raises on exception - - :param qclient: A neutronclient - :param router_id: The id of the router to migrate - :param agent_id: The id of the l3 agent to migrate from - :param target_id: The id of the l3 agent to migrate to - """ - - # N.B. The neutron API will return "success" even when there is a - # subsequent failure during the add or remove process so we must check to - # ensure the router has been added or removed - - # remove the router from the dead agent - qclient.remove_router_from_l3_agent(agent_id, router_id) - - # ensure it is removed or log an error - if router_id in list_routers_on_l3_agent(qclient, agent_id): - LOG.exception("Failed to remove router_id=%s from agent_id=%s", - router_id, agent_id) - - # add the router id to a live agent - router_body = {'router_id': router_id} - qclient.add_router_to_l3_agent(target_id, router_body) - - # ensure it is removed or log an error - if router_id not in list_routers_on_l3_agent(qclient, target_id): - LOG.exception("Failed to add router_id=%s from agent_id=%s", - router_id, agent_id) - - -def list_networks(qclient): - """Return a list of network objects - - :param qclient: A neutronclient - """ - - resp = qclient.list_networks() - LOG.debug("list_networks: %s", resp) - return resp['networks'] - - -def list_dhcp_agent_networks(qclient, agent_id): - """Return a list of network ids assigned to a particular DHCP agent - - :param qclient: A neutronclient - :param agent_id: A DHCP agent id - """ - - resp = qclient.list_networks_on_dhcp_agent(agent_id) - LOG.debug("list_networks_on_dhcp_agent: %s", resp) - return [s['id'] for s in resp['networks']] - - -def list_routers(qclient): - """Return a list of router objects - - :param qclient: A neutronclient - - # {'routers': [ - # {u'status': u'ACTIVE', - # u'external_gateway_info': - # {u'network_id': u'b970297c-d80e-4527-86d7-e49d2da9fdef'}, - # u'name': u'router1', - # u'admin_state_up': True, - # u'tenant_id': u'5603b97ee7f047ea999e25492c7fcb23', - # u'routes': [], - # u'id': u'0a122e5c-1623-412e-8c53-a1e21d1daff8'} - # ]} - - """ - - resp = qclient.list_routers() - LOG.debug("list_routers: %s", resp) - # Filter routers to not include HA routers - return [i for i in resp['routers'] if not i.get('ha')] - - -def list_routers_on_l3_agent(qclient, agent_id): - """Return a list of router ids on an agent - - :param qclient: A neutronclient - """ - - resp = qclient.list_routers_on_l3_agent(agent_id) - LOG.debug("list_routers_on_l3_agent: %s", resp) - return [r['id'] for r in resp['routers'] if not r.get('ha')] - - -def list_agents(qclient, agent_type=None): - """Return a list of agent objects - - :param qclient: A neutronclient - - - # {u'agents': [ - - # {u'binary': u'neutron-openvswitch-agent', - # u'description': None, - # u'admin_state_up': True, - # u'heartbeat_timestamp': u'2013-07-02 22:20:25', - # u'alive': True, - # u'topic': u'N/A', - # u'host': u'o3r3.int.san3.attcompute.com', - # u'agent_type': u'Open vSwitch agent', - # u'created_at': u'2013-07-02 14:50:57', - # u'started_at': u'2013-07-02 14:50:57', - # u'id': u'3a577f1d-d86e-4f1a-a395-8d4c8e4df1e2', - # u'configurations': {u'devices': 10}}, - - # {u'binary': u'neutron-dhcp-agent', - # u'description': None, - # u'admin_state_up': True, - # u'heartbeat_timestamp': u'2013-07-02 22:20:23', - # u'alive': True, - # u'topic': u'dhcp_agent', - # u'host': u'o5r4.int.san3.attcompute.com', - # u'agent_type': u'DHCP agent', - # u'created_at': u'2013-06-26 16:21:02', - # u'started_at': u'2013-06-28 13:32:52', - # u'id': u'3e8be28e-05a0-472b-9288-a59f8d8d2271', - # u'configurations': { - # u'subnets': 4, - # u'use_namespaces': True, - # u'dhcp_driver': u'neutron.agent.linux.dhcp.Dnsmasq', - # u'networks': 4, - # u'dhcp_lease_time': 120, - # u'ports': 38}}, - - - # {u'binary': u'neutron-l3-agent', - # u'description': None, - # u'admin_state_up': True, - # u'heartbeat_timestamp': u'2013-07-02 22:20:23', - # u'alive': True, - # u'topic': u'l3_agent', - # u'host': u'o3r3.int.san3.attcompute.com', - # u'agent_type': u'L3 agent', - # u'created_at': u'2013-07-02 14:50:58', - # u'started_at': u'2013-07-02 18:00:55', - # u'id': u'6efe494a-616c-41ea-9c8f-2c592f4d46ff', - # u'configurations': { - # u'router_id': u'', - # u'handle_internal_only_routers': True, - # u'use_namespaces': True, - # u'routers': 5, - # u'interfaces': 3, - # u'floating_ips': 9, - # u'interface_driver': - # u'neutron.agent.linux.interface.OVSInterfaceDriver', - # u'ex_gw_ports': 3}}, - - """ - - resp = qclient.list_agents() - LOG.debug("list_agents: %s", resp) - if agent_type: - return [agent for agent in resp['agents'] - if agent['agent_type'] == agent_type] - return resp['agents'] - - -def agent_alive_id_list(agent_list, agent_type): - """Return a list of agents that are alive from an API list of agents - - :param agent_list: API response for list_agents() - - """ - return [agent['id'] for agent in agent_list - if agent['agent_type'] == agent_type and agent['alive'] is True] - - -def agent_dead_id_list(agent_list, agent_type): - """Return a list of agents that are dead from an API list of agents - - :param agent_list: API response for list_agents() - - """ - return [agent['id'] for agent in agent_list - if agent['agent_type'] == agent_type and agent['alive'] is False] - - -if __name__ == '__main__': - args = parse_args() - setup_logging(args) - - try: - run(args) - sys.exit(0) - except Exception as err: - LOG.error(err) - sys.exit(1) - except KeyboardInterrupt: - sys.exit(1) diff --git a/templates/neutron_ha_tool.sh.j2 b/templates/neutron_ha_tool.sh.j2 deleted file mode 100644 index 96ab1583..00000000 --- a/templates/neutron_ha_tool.sh.j2 +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2014, Rackspace US, 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. - -set -e - -LOCKFILE="/var/run/neutron_ha_tool.lock" - -# Trap any errors that might happen in executing the script -trap my_trap_handler ERR - -function my_trap_handler { - kill_job -} - -function unlock { - rm "${LOCKFILE}" -} - -function do_job { - # Do a given job - logger "$({{ do_job }})" -} - -function cooldown { - # Sleep for a given amount of time - sleep {{ sleep_time }} -} - -function kill_job { - # If the job needs killing kill the pid and unlock the file. - PID="$(cat ${LOCKFILE})" - unlock - if [ -f "${LOCKFILE}" ]; then - kill -9 "${PID}" - fi -} - -if [ ! -f "${LOCKFILE}" ]; then - echo $$ | tee "${LOCKFILE}" - do_job - cooldown - unlock -else - if [ "$(find ${LOCKFILE} -mmin +15)" ]; then - logger "Stale pid found for ${LOCKFILE}. Killing any left over processes and unlocking" - kill_job - fi -fi