confdb.py 8.27 KB
Newer Older
Dmitry Volodin's avatar
Fix  
Dmitry Volodin committed
1
# ----------------------------------------------------------------------
Dmitry Volodin's avatar
Dmitry Volodin committed
2
# ./noc confdb
Dmitry Volodin's avatar
Fix  
Dmitry Volodin committed
3
# ----------------------------------------------------------------------
4
# Copyright (C) 2007-2019 The NOC Project
Dmitry Volodin's avatar
Fix  
Dmitry Volodin committed
5
6
# See LICENSE for details
# ----------------------------------------------------------------------
Dmitry Volodin's avatar
Dmitry Volodin committed
7
8

# Python modules
9
import argparse
10
import os
Dmitry Volodin's avatar
Dmitry Volodin committed
11
12
13
14

# NOC modules
from noc.core.management.base import BaseCommand
from noc.config import config
15
16
from noc.core.mongo.connection import connect
from noc.core.profile.loader import loader
17
18
from noc.core.text import format_table
from noc.core.comp import smart_text
Dmitry Volodin's avatar
Dmitry Volodin committed
19
20
21
22
23
24
25
26


class Command(BaseCommand):
    PREFIX = config.path.cp_new

    def add_arguments(self, parser):
        subparsers = parser.add_subparsers(dest="cmd")
        # syntax command
27
        syntax_parser = subparsers.add_parser("syntax")
28
        syntax_parser.add_argument("--profile", help="Profile Name")
29
        syntax_parser.add_argument("path", nargs=argparse.REMAINDER)
30
31
        # tokenizer command
        tokenizer_parser = subparsers.add_parser("tokenizer")
32
        tokenizer_parser.add_argument("--object", type=smart_text, help="Managed Object ID")
33
34
35
36
        tokenizer_parser.add_argument("--profile", help="Profile Name")
        tokenizer_parser.add_argument("--config", help="Config Path")
        # config command
        normalizer_parser = subparsers.add_parser("normalizer")
37
        normalizer_parser.add_argument("--object", type=smart_text, help="Managed Object ID")
38
39
        normalizer_parser.add_argument("--profile", help="Profile Name")
        normalizer_parser.add_argument("--config", help="Config Path")
40
41
42
43
44
45
        # query command
        query_parser = subparsers.add_parser("query")
        query_parser.add_argument("--object", type=smart_text, help="Managed Object ID")
        query_parser.add_argument("--profile", help="Profile Name")
        query_parser.add_argument("--config", help="Config Path")
        query_parser.add_argument("query", help="Query request")
46
47
48
49
50
51
        # query command
        dump_parser = subparsers.add_parser("dump")
        dump_parser.add_argument(
            "--show-hints", action="store_true", help="Disable cleanup hints section"
        )
        dump_parser.add_argument("--object", type=smart_text, help="Managed Object ID")
Dmitry Volodin's avatar
Dmitry Volodin committed
52
53
54
55

    def handle(self, cmd, *args, **options):
        return getattr(self, "handle_%s" % cmd)(*args, **options)

56
    def handle_syntax(self, path=None, profile=None, *args, **kwargs):
57
        def dump_node(node, level=0, recursive=True):
Dmitry Volodin's avatar
Dmitry Volodin committed
58
59
60
61
62
63
64
65
66
67
            indent = "  " * level
            if node.name:
                label = "<%s>" % node.name
            elif node.token is None:
                label = "ANY"
            else:
                label = node.token
            if node.multi:
                label = "*%s" % label
            self.print("%s%s" % (indent, label))
68
            if recursive and node.children:
Dmitry Volodin's avatar
Dmitry Volodin committed
69
70
71
                for nc in node.children:
                    dump_node(nc, level + 1)

72
73
74
75
76
77
78
79
80
81
82
83
        def find_root(children, rest_path, level=0):
            if not rest_path:
                return children
            if len(children) == 1 and not children[0].token:
                dump_node(children[0], level, recursive=False)
                return find_root(children[0].children, rest_path[1:], level=level + 1)
            p = rest_path[0]
            for cc in children:
                if cc.token == p:
                    dump_node(cc, level, recursive=False)
                    return find_root(cc.children, rest_path[1:], level=level + 1)

Dmitry Volodin's avatar
Dmitry Volodin committed
84
        from noc.core.confdb.syntax.base import SYNTAX
85
        from noc.core.handler import get_handler
Dmitry Volodin's avatar
Dmitry Volodin committed
86

87
88
89
90
91
92
93
94
95
        s = SYNTAX
        if profile:
            p = loader.get_profile(profile)
            if not p:
                self.die("Invalid profile: %s" % profile)
            n_handler, n_config = p.get_config_normalizer(self)
            n_cls = get_handler("noc.sa.profiles.%s.confdb.normalizer.%s" % (p.name, n_handler))
            s = n_cls.SYNTAX
        root = find_root(s, path)
96
97
98
99
        if not root:
            return
        for c in root:
            dump_node(c, level=len(path) if path else 0)
Dmitry Volodin's avatar
Dmitry Volodin committed
100

101
102
103
104
105
106
107
108
109
    def handle_tokenizer(self, object=None, profile=None, config=None, *args, **kwargs):
        cfg = None
        if config:
            if not os.path.exists(config):
                self.die("File not found: %s" % config)
            with open(config) as f:
                cfg = f.read()
        if object:
            connect()
110
111
112
            from noc.sa.models.managedobject import ManagedObject

            mo = ManagedObject.objects.get(name=object)
113
114
115
116
117
118
119
120
121
122
            if not mo:
                self.die("Managed Object not found")
        elif profile:
            p = loader.get_profile(profile)
            if not p:
                self.die("Invalid profile: %s" % profile)
            if not cfg:
                self.die("Specify config file with --config option")
            # Mock up tokenizer
            connect()
123
124
            from noc.sa.models.managedobject import ManagedObject

125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
            mo = ManagedObject.mock_object(profile=profile)
        else:
            self.die("Eigther object or profile must be set")
        tokenizer = mo.iter_config_tokens(config=cfg)
        for token in tokenizer:
            self.print(token)

    def handle_normalizer(self, object=None, profile=None, config=None, *args, **kwargs):
        cfg = None
        if config:
            if not os.path.exists(config):
                self.die("File not found: %s" % config)
            with open(config) as f:
                cfg = f.read()
        if object:
140
141
            from noc.sa.models.managedobject import ManagedObject

142
            connect()
143
            mo = ManagedObject.objects.get(name=object)
144
145
146
147
148
149
150
151
152
153
            if not mo:
                self.die("Managed Object not found")
        elif profile:
            p = loader.get_profile(profile)
            if not p:
                self.die("Invalid profile: %s" % profile)
            if not cfg:
                self.die("Specify config file with --config option")
            # Mock up tokenizer
            connect()
154
155
            from noc.sa.models.managedobject import ManagedObject

156
157
158
159
160
161
162
            mo = ManagedObject.mock_object(profile=profile)
        else:
            self.die("Eigther object or profile must be set")
        normalizer = mo.iter_normalized_tokens(config=cfg)
        for token in normalizer:
            self.print(token)

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
    def handle_query(self, object=None, profile=None, config=None, query=None, *args, **kwargs):
        cfg = None
        if config:
            if not os.path.exists(config):
                self.die("File not found: %s" % config)
            with open(config) as f:
                cfg = f.read()
        if object:
            connect()
            from noc.sa.models.managedobject import ManagedObject

            mo = ManagedObject.objects.get(name=object)
            if not mo:
                self.die("Managed Object not found")
        elif profile:
            p = loader.get_profile(profile)
            if not p:
                self.die("Invalid profile: %s" % profile)
            if not cfg:
                self.die("Specify config file with --config option")
            # Mock up tokenizer
            connect()
            from noc.sa.models.managedobject import ManagedObject

            mo = ManagedObject.mock_object(profile=profile)
        else:
            self.die("Eigther object or profile must be set")
        confdb = mo.get_confdb()
        headers = []
        table = []
        width = []
        for r in confdb.query(query):
            row = []
            for key in r:
                if key not in headers:
                    headers += [key]
                    width += [40]
arthur-zzz's avatar
arthur-zzz committed
200
                row.insert(headers.index(key), r[key])
201
202
203
204
205
206
            table += [row]
        if table:
            self.print("Result:\n", format_table(width, [headers] + table))
        else:
            self.print("Result:")

207
208
209
210
211
212
213
214
215
216
217
    def handle_dump(self, object=None, show_hints=False, *args, **kwargs):
        if object:
            connect()
            from noc.sa.models.managedobject import ManagedObject

            mo = ManagedObject.objects.get(name=object)
            if not mo:
                self.die("Managed Object not found")
        confdb = mo.get_confdb(cleanup=not show_hints)
        self.print(confdb.dump())

Dmitry Volodin's avatar
Dmitry Volodin committed
218
219
220

if __name__ == "__main__":
    Command().run()