update to use Quantum rpc sync state
This commit is contained in:
parent
5936b0bd71
commit
6e78e4ca2d
|
@ -1,10 +1,14 @@
|
|||
import socket
|
||||
import time
|
||||
import uuid
|
||||
|
||||
import netaddr
|
||||
from quantumclient.v2_0 import client
|
||||
|
||||
from akanda.rug.openstack.common import importutils
|
||||
from akanda.rug.openstack.common import cfg
|
||||
from akanda.rug.openstack.common import context
|
||||
from akanda.rug.openstack.common.rpc import proxy
|
||||
|
||||
|
||||
# copied from Quantum source
|
||||
|
@ -12,8 +16,8 @@ DEVICE_OWNER_ROUTER_MGT = "network:router_management"
|
|||
DEVICE_OWNER_ROUTER_INT = "network:router_interface"
|
||||
DEVICE_OWNER_ROUTER_GW = "network:router_gateway"
|
||||
DEVICE_OWNER_FLOATINGIP = "network:floatingip"
|
||||
|
||||
DEVICE_OWNER_RUG = "akanda:rug"
|
||||
DEVICE_OWNER_RUG = "network:akanda"
|
||||
PLUGIN_RPC_TOPIC = 'q-plugin'
|
||||
|
||||
|
||||
class Router(object):
|
||||
|
@ -266,28 +270,53 @@ class AkandaExtClientWrapper(client.Client):
|
|||
params=params)
|
||||
|
||||
|
||||
class L3PluginApi(proxy.RpcProxy):
|
||||
"""Agent side of the Qunatum l3 agent RPC API."""
|
||||
|
||||
BASE_RPC_API_VERSION = '1.0'
|
||||
|
||||
def __init__(self, topic, host):
|
||||
super(L3PluginApi, self).__init__(
|
||||
topic=topic, default_version=self.BASE_RPC_API_VERSION)
|
||||
self.host = host
|
||||
|
||||
def get_routers(self, router_id=None):
|
||||
"""Make a remote process call to retrieve the sync data for routers."""
|
||||
router_ids = [router_id] if router_id else None
|
||||
retval = self.call(context.get_admin_context(),
|
||||
self.make_msg('sync_routers', host=self.host,
|
||||
router_ids=router_ids),
|
||||
topic=self.topic)
|
||||
return retval
|
||||
|
||||
|
||||
|
||||
class Quantum(object):
|
||||
def __init__(self, conf):
|
||||
self.conf = conf
|
||||
self.client = AkandaExtClientWrapper(
|
||||
self.api_client = AkandaExtClientWrapper(
|
||||
username=conf.admin_user,
|
||||
password=conf.admin_password,
|
||||
tenant_name=conf.admin_tenant_name,
|
||||
auth_url=conf.auth_url,
|
||||
auth_strategy=conf.auth_strategy,
|
||||
auth_region=conf.auth_region)
|
||||
auth_region=conf.auth_region
|
||||
)
|
||||
self.rpc_client = L3PluginApi(PLUGIN_RPC_TOPIC, cfg.CONF.host)
|
||||
|
||||
def get_routers(self):
|
||||
"""Return a list of routers."""
|
||||
return [Router.from_dict(r) for r in
|
||||
self.client.list_routers()['routers']]
|
||||
self.rpc_client.get_routers()]
|
||||
|
||||
def get_router_detail(self, router_id):
|
||||
"""Return detailed information about a router and it's networks."""
|
||||
return Router.from_dict(self.client.show_router(router_id)['router'])
|
||||
return Router.from_dict(
|
||||
self.rpc_client.get_routers(router_id=router_id)[0]
|
||||
)
|
||||
|
||||
def get_router_for_tenant(self, tenant_id):
|
||||
routers = self.client.list_routers(tenant_id=tenant_id)['routers']
|
||||
routers = self.api_client.list_routers(tenant_id=tenant_id)['routers']
|
||||
|
||||
if routers:
|
||||
return Router.from_dict(routers[0])
|
||||
|
@ -296,25 +325,25 @@ class Quantum(object):
|
|||
|
||||
def get_network_ports(self, network_id):
|
||||
return [Port.from_dict(p) for p in
|
||||
self.client.list_ports(network_id=network_id)['ports']]
|
||||
self.api_client.list_ports(network_id=network_id)['ports']]
|
||||
|
||||
def get_network_subnets(self, network_id):
|
||||
return [Subnet.from_dict(s) for s in
|
||||
self.client.list_subnets(network_id=network_id)['subnets']]
|
||||
self.api_client.list_subnets(network_id=network_id)['subnets']]
|
||||
|
||||
def get_addressgroups(self, tenant_id):
|
||||
return [AddressGroup.from_dict(g) for g in
|
||||
self.client.list_addressgroups(
|
||||
self.api_client.list_addressgroups(
|
||||
tenant_id=tenant_id)['addressgroups']]
|
||||
|
||||
def get_filterrules(self, tenant_id):
|
||||
return [FilterRule.from_dict(r) for r in
|
||||
self.client.list_filterrules(
|
||||
self.api_client.list_filterrules(
|
||||
tenant_id=tenant_id)['filterrules']]
|
||||
|
||||
def get_portforwards(self, tenant_id):
|
||||
return [PortForward.from_dict(f) for f in
|
||||
self.client.list_portforwards(
|
||||
self.api_client.list_portforwards(
|
||||
tenant_id=tenant_id)['portforwards']]
|
||||
|
||||
def create_router_management_port(self, router_id):
|
||||
|
@ -322,16 +351,16 @@ class Quantum(object):
|
|||
network_id=self.conf.management_network_id,
|
||||
device_owner=DEVICE_OWNER_ROUTER_MGT
|
||||
)
|
||||
response = self.client.create_port(dict(port=port_dict))
|
||||
response = self.api_client.create_port(dict(port=port_dict))
|
||||
port = Port.from_dict(response['port'])
|
||||
args = dict(port_id=port.id, owner=DEVICE_OWNER_ROUTER_MGT)
|
||||
self.client.add_interface_router(router_id, args)
|
||||
self.api_client.add_interface_router(router_id, args)
|
||||
|
||||
return port
|
||||
|
||||
def delete_router_management_port(self, router_id, port_id):
|
||||
args = dict(port_id=port_id, owner=DEVICE_OWNER_ROUTER_MGT)
|
||||
self.client.remove_interface_router(router_id, args)
|
||||
self.api_client.remove_interface_router(router_id, args)
|
||||
|
||||
def create_router_external_port(self, router):
|
||||
network_args = {'network_id': self.conf.external_network_id}
|
||||
|
@ -341,7 +370,7 @@ class Quantum(object):
|
|||
'external_gateway_info': network_args
|
||||
}
|
||||
|
||||
r = self.client.update_router(router.id, body=dict(router=update_args))
|
||||
r = self.api_client.update_router(router.id, body=dict(router=update_args))
|
||||
return Router.from_dict(r['router']).external_port
|
||||
|
||||
def ensure_local_service_port(self):
|
||||
|
@ -353,27 +382,36 @@ class Quantum(object):
|
|||
query_dict = dict(device_owner=DEVICE_OWNER_RUG,
|
||||
device_id=host_id)
|
||||
|
||||
ports = self.client.list_ports(**query_dict)['ports']
|
||||
ports = self.api_client.list_ports(**query_dict)['ports']
|
||||
|
||||
ip_address = get_local_service_ip(self.conf)
|
||||
|
||||
if ports:
|
||||
port = Port.from_dict(ports[0])
|
||||
else:
|
||||
# create the missing local port
|
||||
port_dict = dict(admin_state_up=True,
|
||||
network_id=self.conf.management_network_id,
|
||||
device_owner=DEVICE_OWNER_RUG,
|
||||
device_id=host_id)
|
||||
port_dict = dict(
|
||||
admin_state_up=True,
|
||||
network_id=self.conf.management_network_id,
|
||||
device_owner=DEVICE_OWNER_RUG,
|
||||
device_id=host_id,
|
||||
fixed_ips=[{
|
||||
'ip_address': ip_address.split('/')[0],
|
||||
'subnet_id': self.conf.management_subnet_id
|
||||
}]
|
||||
)
|
||||
|
||||
port = Port.from_dict(
|
||||
self.client.create_port(dict(port=port_dict))['port'])
|
||||
self.api_client.create_port(dict(port=port_dict))['port'])
|
||||
|
||||
driver.plug(port.network_id,
|
||||
port.id,
|
||||
driver.get_device_name(port),
|
||||
port.mac_address)
|
||||
# add sleep to ensure that port is setup before use
|
||||
time.sleep(1)
|
||||
|
||||
driver.init_l3(driver.get_device_name(port),
|
||||
[get_local_service_ip(self.conf)])
|
||||
driver.init_l3(driver.get_device_name(port), [ip_address])
|
||||
|
||||
return port
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ LOG = logging.getLogger(__name__)
|
|||
|
||||
OPTIONS = [
|
||||
cfg.StrOpt('admin_user'),
|
||||
cfg.StrOpt('admin_password'),
|
||||
cfg.StrOpt('admin_password', secret=True),
|
||||
cfg.StrOpt('admin_tenant_name'),
|
||||
cfg.StrOpt('auth_url'),
|
||||
cfg.StrOpt('auth_strategy', default='keystone'),
|
||||
|
@ -41,22 +41,20 @@ OPTIONS = [
|
|||
cfg.StrOpt('interface_driver'),
|
||||
cfg.StrOpt('ovs_integration_bridge', default='br-int'),
|
||||
cfg.BoolOpt('ovs_use_veth', default=False),
|
||||
cfg.StrOpt('root_helper', default='sudo'),
|
||||
cfg.IntOpt('network_device_mtu'),
|
||||
|
||||
# listen for Quantum notification events
|
||||
cfg.StrOpt('notification_topic',
|
||||
default='notifications.info',
|
||||
help='Quantum notification topic name'),
|
||||
cfg.StrOpt('quantum_control_exchange',
|
||||
default='openstack',
|
||||
help='Quantum control exchange name'),
|
||||
cfg.StrOpt('control_exchange',
|
||||
default='akanda',
|
||||
help='Akanda control exchange name')
|
||||
help='Quantum notification topic name')
|
||||
]
|
||||
|
||||
AGENT_OPTIONS = [
|
||||
cfg.StrOpt('root_helper', default='sudo'),
|
||||
]
|
||||
|
||||
cfg.CONF.register_opts(OPTIONS)
|
||||
cfg.CONF.register_opts(AGENT_OPTIONS, 'AGENT')
|
||||
|
||||
|
||||
class AkandaL3Manager(notification.NotificationMixin,
|
||||
|
@ -66,39 +64,38 @@ class AkandaL3Manager(notification.NotificationMixin,
|
|||
self.quantum = quantum.Quantum(cfg.CONF)
|
||||
self.nova = nova.Nova(cfg.CONF)
|
||||
self.task_mgr = task.TaskManager()
|
||||
|
||||
self.quantum.ensure_local_service_port()
|
||||
|
||||
def init_host(self):
|
||||
def initialize_service_hook(self, started_by):
|
||||
self.sync_state()
|
||||
self.task_mgr.start()
|
||||
self.create_notification_listener(
|
||||
cfg.CONF.notification_topic,
|
||||
cfg.CONF.quantum_control_exchange)
|
||||
cfg.CONF.control_exchange)
|
||||
self.metadata = metadata.create_metadata_signing_proxy(
|
||||
quantum.get_local_service_ip(cfg.CONF).split('/')[0]
|
||||
)
|
||||
|
||||
@periodic_task.periodic_task
|
||||
def begin_health_check(self):
|
||||
def begin_health_check(self, context):
|
||||
LOG.info('start health check queueing')
|
||||
for rtr in self.cache.routers():
|
||||
self.task_mgr.put(self.check_health, rtr)
|
||||
|
||||
@periodic_task.periodic_task(ticks_between_runs=1)
|
||||
def report_bandwidth_usage(self):
|
||||
def report_bandwidth_usage(self, context):
|
||||
LOG.info('start bandwidth usage reporting')
|
||||
for rtr in self.cache.routers():
|
||||
self.task_mgr.put(self.report_bandwidth, rtr)
|
||||
|
||||
@periodic_task.periodic_task(ticks_between_runs=10)
|
||||
def janitor(self):
|
||||
def janitor(self, context):
|
||||
"""Periodically do a full state resync."""
|
||||
LOG.debug('resync router state')
|
||||
self.sync_state()
|
||||
|
||||
@periodic_task.periodic_task(ticks_between_runs=15)
|
||||
def refresh_configs(self):
|
||||
def refresh_configs(self, context):
|
||||
LOG.debug('resync configuration state')
|
||||
for rtr_id in self.cache.keys():
|
||||
self.task_mgr.put(self.update_config, rtr_id)
|
||||
|
@ -113,7 +110,10 @@ class AkandaL3Manager(notification.NotificationMixin,
|
|||
|
||||
@notification.handles('subnet.create.end',
|
||||
'subnet.change.end',
|
||||
'subnet.delete.end')
|
||||
'subnet.delete.end',
|
||||
'port.create.end',
|
||||
'port.change.end',
|
||||
'port.delete.end')
|
||||
def handle_router_subnet_change(self, tenant_id, payload):
|
||||
rtr = self.cache.get_by_tenant_id(tenant_id)
|
||||
if not rtr:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import socket
|
||||
import sys
|
||||
|
||||
import eventlet
|
||||
|
@ -5,24 +6,39 @@ import eventlet
|
|||
from akanda.rug import manager
|
||||
from akanda.rug.openstack.common import cfg
|
||||
from akanda.rug.openstack.common import log
|
||||
from akanda.rug.openstack.common import rpc
|
||||
from akanda.rug.openstack.common.rpc import service as rpc_service
|
||||
from akanda.rug.openstack.common import service
|
||||
|
||||
cfg.CONF.register_opts([
|
||||
cfg.IntOpt('periodic_interval',
|
||||
default=60,
|
||||
help='seconds between running periodic tasks (ie health check)')
|
||||
help='seconds between periodic task runs (ie health check)'),
|
||||
cfg.StrOpt('host',
|
||||
default=socket.getfqdn(),
|
||||
help=_("The hostname Quantum is running on")),
|
||||
])
|
||||
|
||||
|
||||
class PeriodicService(rpc_service.Service):
|
||||
def start(self):
|
||||
super(PeriodicService, self).start()
|
||||
self.tg.add_timer(
|
||||
cfg.CONF.periodic_interval,
|
||||
self.manager.run_periodic_tasks,
|
||||
None,
|
||||
None
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
eventlet.monkey_patch()
|
||||
cfg.CONF(sys.argv[1:])
|
||||
cfg.CONF(sys.argv[1:], project='akanda')
|
||||
log.setup('akanda')
|
||||
|
||||
mgr = manager.AkandaL3Manager()
|
||||
svc = service.Service('akanda', mgr, cfg.CONF.periodic_interval, None)
|
||||
svc.start()
|
||||
svc.wait()
|
||||
svc = PeriodicService(host=cfg.CONF.host, topic='akanda', manager=mgr)
|
||||
service.launch(svc).wait()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
21
etc/rug.ini
21
etc/rug.ini
|
@ -1,27 +1,32 @@
|
|||
[DEFAULT]
|
||||
debug=True
|
||||
versbose=True
|
||||
admin_user=quantum
|
||||
admin_password=password
|
||||
admin_tenant_name=service
|
||||
auth_url=http://192.168.57.100:35357/v2.0/
|
||||
auth_url=http://192.168.57.200:35357/v2.0/
|
||||
auth_strategy=keystone
|
||||
auth_region=RegionOne
|
||||
|
||||
management_prefix=fdca:3ba5:a17a:acda::/64
|
||||
akanda_mgt_service_port=5000
|
||||
|
||||
management_network_id=7860030c-fc43-45d1-88d1-5863a04e9ebf
|
||||
management_subnet_id=25f3586d-fa0a-434a-8001-d4849ab514fd
|
||||
external_network_id=3a9a71ce-8bea-4b6f-82ca-d74ee672895c
|
||||
management_network_id=fff4bc78-4a54-49ad-b4e8-5ccc5a61e10d
|
||||
management_subnet_id=9e08721d-1709-4966-8c14-d6b2bcf6ac80
|
||||
external_network_id=bc42a9fa-2c54-4940-b521-d48055eaf42f
|
||||
|
||||
router_image_uuid=27334edd-49b8-4a2d-8dae-2f37af5126c7
|
||||
router_image_uuid=f32484e8-6d1f-4ab5-9e3b-95b8d0759e52
|
||||
router_instance_flavor=1
|
||||
|
||||
# to plug in rug interface
|
||||
root_helper=sudo
|
||||
interface_driver=quantum.agent.linux.interface.OVSInterfaceDriver
|
||||
ovs_integration_bridge=br-int
|
||||
|
||||
rabbit_password = yetanothersecret
|
||||
rabbit_host = 192.168.57.100
|
||||
rabbit_host = 192.168.57.200
|
||||
|
||||
provider_rules_path=/opt/stack/akanda-rug/akanda/rug/provider_rules.json
|
||||
provider_rules_path=/opt/stack/akanda-rug/etc/provider_rules.json
|
||||
control_exchange = quantum
|
||||
|
||||
[AGENT]
|
||||
root_helper=sudo
|
||||
|
|
Loading…
Reference in New Issue