Completed
Branch prom (d3fc9e)
by Kenny
01:21
created

get_plugins()   B

Complexity

Conditions 5

Size

Total Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 33
rs 8.0894
cc 5
1
# -*- coding: utf-8 -*-
2
"""Plumd main entry point."""
3
import os
4
import sys
5
import time
6
import signal
7
import logging
8
9
import click
0 ignored issues
show
Configuration introduced by
The import click could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
10
11
import plumd
12
import plumd.util
13
import plumd.config
14
from plumd.server.null import NullServer
15
16
PY3 = sys.version_info > (3,)
17
18
__author__ = 'Kenny Freeman'
19
__email__ = '[email protected]'
20
__license__ = "ISCL"
21
__docformat__ = 'reStructuredText'
22
23
24
def get_config(cfile):
25
    """Load configuration from cfile and return a Conf instance from it.
26
27
    :param cfile: Full path to a configuration file.
28
    :type cfile: str
29
    :raises: plumd.ConfigError for invalid configuration
30
    :rtype: plumd.config.conf
31
    """
32
    # get a simple configuration helper object
33
    config = None
34
    try:
35
        config = plumd.config.Conf(cfile).defaults(plumd.DEFAULT_CONFIG)
36
    except plumd.ConfigError as exc:
37
        err = "configuration failed to load: {0} : {1}\n"
38
        sys.stderr.write(err.format(cfile, exc))
39
        sys.exit(1)
40
41
    # ensure log level is known
42
    llevel = config.get('log.level')
43
    if llevel not in plumd.LOG_LEVELS:
44
        llevels = " ".join(list(plumd.LOG_LEVELS.keys()))
45
        sys.stderr.write("unkonwn log level: {0}\n".format(llevel))
46
        sys.stderr.write("valid log levels are: {0}\n".format(llevels))
47
        sys.exit(1)
48
49
    # all done, return our config
50
    return config
51
52
53
def initialize(config):
54
    """Do various init things with the config instance.
55
56
    :param config: a :class:`plumd.config.conf` instance
57
    :type config: plumd.config.conf
58
    """
59
    # set the configured timezone, from:
60
    # http://stackoverflow.com/questions/6321160/python-logging-how-to-set-time-to-gmt
61
    timezone = config.get('tz')
62
    if timezone:
63
        os.environ['TZ'] = timezone
64
        time.tzset()
65
66
    # add hostname metadata
67
    if config.get('meta.hostname'):
68
        meta = config.get('meta')
69
        # meta is a list of single item {'key': 'value'} dicts
70
        for entry in meta:
71
            for key, val in entry.items():
72
                if key == 'hostname':
73
                    err = "meta.hostname: hostname in meta already: {0} : {1}\n"
74
                    sys.stderr.write(err.format(val, config.path))
75
                    sys.exit(1)
76
        meta.append({'hostname': plumd.util.get_hostname()})
77
        config.set_conf('meta', meta)
78
79
    return config
80
81
82
def get_log(config):
83
    """Return a configured logger.
84
85
    :param config: a :class:`plumd.config.conf` instance
86
    :type config: plumd.config.conf
87
    :param src: all log entries generated are tagged with src=<src>
88
    :type src: str
89
90
    :rtype: logging.Logger
91
    """
92
    # create logger
93
    handler = logging.StreamHandler(sys.stdout)
94
    formatter = logging.Formatter(config.get('log.format'))
95
    handler.setFormatter(formatter)
96
    stdlog = logging.getLogger()
97
    stdlog.addHandler(handler)
98
    stdlog.setLevel(plumd.LOG_LEVELS[config.get('log.level')])
99
    return stdlog
100
101
102
@click.group()
103
def cli():
104
    """Main entry point for plumd."""
105
    # placeholder function to allow sub-commands
106
    pass
107
108
109
@cli.command()
110
@click.option("--cdir",  help="Configuration directory to output to", type=click.Path())
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
@click.option("--cdir", help="Configuration directory to output to", type=click.Path())
^
Loading history...
111
@click.option("--mode", default=plumd.DEFAULT_SERVER, help="What mode to run in", type=click.Choice(['null', 'prometheus']))
112
def generate(cdir, mode):
0 ignored issues
show
Unused Code introduced by
The argument cdir seems to be unused.
Loading history...
Unused Code introduced by
The argument mode seems to be unused.
Loading history...
113
    """Create default configurations under the specified path."""
114
    # todo - create functionality to support this
115
    print("todo..")
116
    # generate configuration file from defaults, save to plumd.yaml
117
    print("gen main config here")
118
    # create Conf object from config
119
    print("load main config here")
120
    # scan for available plugins
121
    print("scan for plugins here")
122
    # create configurations with name only for each reader, all render plugins
123
    print("generate config for each reader plugin")
124
    # create configurations with name only for each render
125
    print("generate config for each render plugin")
126
    # create configurations with name only for each writer, first render plugin found
127
    print("generate config for each writer plugin")
128
    # load all plugins
129
    print("load all plugins here")
130
    # write all configurations back to dir
131
    print("write all configurations here")
132
133
134
135
136
@cli.command()
137
@click.option("--cfile", default=plumd.DEFAULT_CONFIG_FILE, help="Main configuration filename", type=click.Path())
138
@click.option("--mode", default=plumd.DEFAULT_SERVER, help="What mode to run in", type=click.Choice(['null', 'prometheus']))
139
def test(cfile, mode):
140
    """Test the provided configuration and exit."""
141
    # assumption: if we can load a server without Exceptions, then the config
142
    # is likely OK.
143
144
    # get our configuration
145
    config = get_config(cfile)
146
147
    # ensure log level is known
148
    llevel = config.get('log.level')
149
    if llevel not in plumd.LOG_LEVELS:
150
        llevels = " ".join(list(plumd.LOG_LEVELS.keys()))
151
        sys.stderr.write("unkonwn log level: {0}\n".format(llevel))
152
        sys.stderr.write("valid log levels are: {0}\n".format(llevels))
153
        sys.exit(1)
154
155
    # initialize it
156
    config = initialize(config)
157
158
    # create a logger
159
    log = get_log(config=config)
160
    vinfo = sys.version_info
161
    ver_str = "{0}.{1}.{2}".format(vinfo[0], vinfo[1], vinfo[2])
162
    msg = "starting - running on python {0}".format(ver_str)
163
    log.info(msg)
164
165
    srv = None
166
    if mode == "null":
167
        srv = NullServer(log, config)
168
    elif mode == "prometheus":
169
        log.error("not implemented: mode=prometheus")
170
        sys.exit(1)
171
    srv.stop()
172
173
    log.info("Configuration and plugins loaded OK")
174
    sys.exit(0)
175
176
177
@cli.command()
178
@click.option("--cfile", default=plumd.DEFAULT_CONFIG_FILE, help="Main configuration filename", type=click.Path())
179
@click.option("--mode", default=plumd.DEFAULT_SERVER, help="What mode to run in", type=click.Choice(['null', 'prometheus']))
180
def run(cfile, mode):
181
    """Main entry point for plumd.
182
183
    :param config: Full path to the main configuration file.
184
    :type config: str
185
    :param mode: The 'server' mode to run in.
186
    :type mode: str
187
    """
188
    # setup signal handling
189
    sig_wait = [signal.SIGINT, signal.SIGTERM, signal.SIGQUIT]
190
    sig_ignore = [signal.SIGUSR1, signal.SIGUSR2, signal.SIGHUP]
191
    swait = plumd.util.SignalWaiter(sig_wait=sig_wait, sig_ignore=sig_ignore)
192
193
    # get our configuration
194
    config = get_config(cfile)
195
196
    # ensure log level is known
197
    llevel = config.get('log.level')
198
    if llevel not in plumd.LOG_LEVELS:
199
        llevels = " ".join(list(plumd.LOG_LEVELS.keys()))
200
        sys.stderr.write("unkonwn log level: {0}\n".format(llevel))
201
        sys.stderr.write("valid log levels are: {0}\n".format(llevels))
202
        sys.exit(1)
203
204
    # initialize it
205
    config = initialize(config)
206
207
    # create a logger
208
    log = get_log(config=config)
209
    vinfo = sys.version_info
210
    ver_str = "{0}.{1}.{2}".format(vinfo[0], vinfo[1], vinfo[2])
211
    msg = "starting - running on python {0}".format(ver_str)
212
    log.info(msg)
213
214
    srv = None
215
    if mode == "null":
216
        srv = NullServer(log, config)
217
    elif mode == "prometheus":
218
        log.error("not implemented: mode=prometheus")
219
        sys.exit(1)
220
221
    # start server
222
    srv.start()
223
224
    # all set, now wait for the exit signal
225
    log.info("running")
226
    swait.wait()
227
228
    # stop readers/writers/bridge
229
    log.info("stopping")
230
    srv.stop()
231
232
    # all done, exit
233
    log.info("exiting")
234
    sys.exit(0)
235
236
237
if __name__ == "__main__":
238
    cli()
239