blob: 553df6f541550f9d250fb3018781f5e5f87b42fe [file] [log] [blame]
Scott Bakerc3ce3e72016-06-20 17:35:19 -07001import os
2import requests
3import socket
4import sys
5import base64
6from django.db.models import F, Q
7from xos.config import Config
8from synchronizers.base.syncstep import SyncStep
9from core.models import Service, Port, Controller, Tag, Tenant
10from core.models.service import COARSE_KIND
11from services.vsg.models import VSGTenant
12from xos.logger import Logger, logging
13from requests.auth import HTTPBasicAuth
14
15# hpclibrary will be in steps/..
16parentdir = os.path.join(os.path.dirname(__file__),"..")
17sys.path.insert(0,parentdir)
18
19logger = Logger(level=logging.INFO)
20
21# XXX should save and load this
22glo_saved_vtn_maps = []
23
24class SyncPortAddresses(SyncStep):
25 requested_interval = 0 # 3600
26 provides=[Port]
27 observes=Port
28
29 def __init__(self, **args):
30 SyncStep.__init__(self, **args)
31
32 def call(self, **args):
33 global glo_saved_vtn_maps
34
35 logger.info("sync'ing vsg tenant to port addresses")
36
37 # build up a dictionary of port-->[wan_addrs] mappings
38 port_addrs = {}
39 for vsg in VSGTenant.get_tenant_objects().all():
40 if not vsg.instance:
41 logger.info("skipping vsg %s because it has no instance" % vsg)
42
43 wan_ip = vsg.wan_container_ip
44 if not wan_ip:
45 logger.info("skipping vsg %s because it has no wan_container_ip" % vsg)
46
47 wan_mac = vsg.wan_container_mac
48 if not wan_mac:
49 logger.info("skipping vsg %s because it has no wan_container_mac" % vsg)
50
51 lan_network = vsg.get_lan_network(vsg.instance)
52 if not lan_network:
53 logger.info("skipping vsg %s because it has no lan_network" % vsg)
54
55 lan_port = Port.objects.filter(instance = vsg.instance, network=lan_network)
56 if not lan_port:
57 logger.info("skipping vsg %s because it has no lan_port" % vsg)
58 lan_port = lan_port[0]
59
60 if not lan_port.port_id:
61 logger.info("skipping vsg %s because its lan_port has no port_id" % vsg)
62
63 if not (lan_port.pk in port_addrs):
64 port_addrs[lan_port.pk] = []
65 entry = {"mac_address": wan_mac, "ip_address": wan_ip}
66 addr_pairs = port_addrs[lan_port.pk]
67 if not entry in addr_pairs:
68 addr_pairs.append(entry)
69
70 # now do the VM_WAN_IP from the instance
71 if vsg.instance:
72 wan_vm_ip = vsg.wan_vm_ip
73 wan_vm_mac = vsg.wan_vm_mac
74 entry = {"mac_address": wan_vm_mac, "ip_address": wan_vm_ip}
75 if not entry in addr_pairs:
76 addr_pairs.append(entry)
77
78 # Get all ports in all controllers
79 ports_by_id = {}
80 for controller in Controller.objects.all():
81 if not controller.admin_tenant:
82 logger.info("controller %s has no admin_tenant" % controller)
83 continue
84 try:
85 driver = self.driver.admin_driver(controller = controller)
86 ports = driver.shell.quantum.list_ports()["ports"]
87 except:
88 logger.log_exc("failed to get ports from controller %s" % controller)
89 continue
90
91 for port in ports:
92 ports_by_id[port["id"]] = port
93
94 for port_pk in port_addrs.keys():
95 port = Port.objects.get(pk=port_pk)
96 addr_pairs = port_addrs[port_pk]
97 neutron_port = ports_by_id.get(port.port_id,None)
98 if not neutron_port:
99 logger.info("failed to get neutron port for port %s" % port)
100 continue
101
102 ips = [x["ip_address"] for x in addr_pairs]
103
104 changed = False
105
106 # delete addresses in neutron that don't exist in XOS
107 aaps = neutron_port.get("allowed_address_pairs", [])
108 for aap in aaps[:]:
109 if not aap["ip_address"] in ips:
110 logger.info("removing address %s from port %s" % (aap["ip_address"], port))
111 aaps.remove(aap)
112 changed = True
113
114 aaps_ips = [x["ip_address"] for x in aaps]
115
116 # add addresses in XOS that don't exist in neutron
117 for addr in addr_pairs:
118 if not addr["ip_address"] in aaps_ips:
119 logger.info("adding address %s to port %s" % (addr, port))
120 aaps.append( addr )
121 aaps_ips.append(addr["ip_address"])
122 changed = True
123
124 if changed:
125 logger.info("updating port %s" % port)
126 driver.shell.quantum.update_port(port.port_id, {"port": {"allowed_address_pairs": aaps}})
127
128
129
130
131
132
133