summaryrefslogtreecommitdiffstats
path: root/app/discover/events/event_router_add.py
blob: 3c1c9e2b9a6d5390f800cc076fd0ab9e31085256 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
###############################################################################
# Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems)   #
# and others                                                                  #
#                                                                             #
# All rights reserved. This program and the accompanying materials            #
# are made available under the terms of the Apache License, Version 2.0       #
# which accompanies this distribution, and is available at                    #
# http://www.apache.org/licenses/LICENSE-2.0                                  #
###############################################################################
import datetime
from functools import partial

from discover.events.event_base import EventBase, EventResult
from discover.events.event_port_add import EventPortAdd
from discover.events.event_subnet_add import EventSubnetAdd
from discover.fetchers.cli.cli_fetch_host_vservice import CliFetchHostVservice
from discover.link_finders.find_links_for_vservice_vnics import \
    FindLinksForVserviceVnics
from discover.scanner import Scanner
from utils.util import decode_router_id, encode_router_id


class EventRouterAdd(EventBase):

    def add_router_document(self, env, network_id, router_doc, host):
        router_doc["environment"] = env
        router_doc["id_path"] = "{}/{}-vservices/{}-vservices-routers/{}"\
                                .format(host['id_path'], host['id'],
                                        host['id'], router_doc['id'])
        router_doc['last_scanned'] = datetime.datetime.utcnow()
        router_doc['name_path'] = "{}/Vservices/Gateways/{}"\
                                  .format(host['name_path'],
                                          router_doc['name'])
        router_doc['network'] = []
        if network_id:
            router_doc['network'] = [network_id]

        router_doc['object_name'] = router_doc['name']
        router_doc['parent_id'] = host['id'] + "-vservices-routers"
        router_doc['show_in_tree'] = True
        router_doc['type'] = "vservice"

        self.inv.set(router_doc)

    def add_children_documents(self, env, project_id, network_id, host, router_doc):

        network_document = self.inv.get_by_id(env, network_id)
        network_name = network_document['name']
        router_id = decode_router_id(router_doc['id'])

        # add port for binding to vservice:router
        subnet_handler = EventSubnetAdd()
        ports_folder = self.inv.get_by_id(env, network_id + '-ports')
        if not ports_folder:
            self.log.info("Ports_folder not found.")
            subnet_handler.add_ports_folder(env, project_id, network_id, network_name)
        add_port_return = subnet_handler.add_port_document(env,
                                                           router_doc['gw_port_id'],
                                                           network_name=network_name)

        # add vnics folder and vnic document
        port_handler = EventPortAdd()
        add_vnic_folder = partial(port_handler.add_vnics_folder,
                                  env=env,
                                  host=host,
                                  object_id=router_id,
                                  object_type='router',
                                  network_name=network_name,
                                  router_name=router_doc['name'])
        add_vnic_document = partial(port_handler.add_vnic_document,
                                    env=env,
                                    host=host,
                                    object_id=router_id,
                                    object_type='router',
                                    network_name=network_name,
                                    router_name=router_doc['name'])

        add_vnic_folder()
        if add_port_return:
            add_vnic_return = add_vnic_document()
            if not add_vnic_return:
                self.log.info("Try to add vnic document again.")
                add_vnic_document()
        else:
            # in some cases, port has been created,
            # but port doc cannot be fetched by OpenStack API
            self.log.info("Try to add port document again.")
            # TODO: #AskCheng - this never returns anything!
            add_port_return = add_vnic_folder()
            # TODO: #AskCheng - this will never evaluate to True!
            if add_port_return is False:
                self.log.info("Try to add vnic document again.")
                add_vnic_document()

    def handle(self, env, values):
        router = values['payload']['router']
        host_id = values["publisher_id"].replace("network.", "", 1)
        project_id = values['_context_project_id']
        router_id = encode_router_id(host_id, router['id'])
        host = self.inv.get_by_id(env, host_id)

        fetcher = CliFetchHostVservice()
        fetcher.set_env(env)
        router_doc = fetcher.get_vservice(host_id, router_id)
        gateway_info = router['external_gateway_info']

        if gateway_info:
            network_id = gateway_info['network_id']
            self.add_router_document(env, network_id, router_doc, host)
            self.add_children_documents(env, project_id, network_id, host, router_doc)
        else:
            self.add_router_document(env, None, router_doc, host)

        # scan links and cliques
        FindLinksForVserviceVnics().add_links(search={"parent_id": router_id})
        scanner = Scanner()
        scanner.set_env(env)
        scanner.scan_cliques()
        self.log.info("Finished router added.")

        return EventResult(result=True,
                           related_object=router_id,
                           display_context=router_id)