Passed
Push — master ( 75d6fe...ae0247 )
by Humberto
01:02 queued 11s
created

kytos.utils.config.KytosConfig.get_metadata()   A

Complexity

Conditions 1

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1.512

Importance

Changes 0
Metric Value
cc 1
eloc 6
nop 1
dl 0
loc 7
ccs 1
cts 5
cp 0.2
crap 1.512
rs 10
c 0
b 0
f 0
1
"""Kytos utils configuration."""
2
# This file is part of kytos-utils.
3
#
4
# Copyright (c) 2016 Kytos Team
5
#
6
# Authors:
7
#    Beraldo Leal <beraldo AT ncc DOT unesp DOT br>
8
9 1
import json
10 1
import logging
11 1
import os
12 1
import re
13 1
import urllib.request
14 1
from collections import namedtuple
15 1
from configparser import ConfigParser
16
17 1
LOG = logging.getLogger(__name__)
18
19
20 1
class KytosConfig():
21
    """Kytos Configs.
22
23
    Read the config file for kytos utils and/or request data for the user in
24
    order to get the correct paths and links.
25
    """
26
27 1
    def __init__(self, config_file='~/.kytosrc'):
28
        """Init method.
29
30
        Receive the config_file as argument.
31
        """
32 1
        self.config_file = os.path.expanduser(config_file)
33 1
        self.debug = False
34 1
        if self.debug:
35
            LOG.setLevel(logging.DEBUG)
36
37
        # allow_no_value=True is used to keep the comments on the config file.
38 1
        self.config = ConfigParser(allow_no_value=True)
39
40
        # Parse the config file. If no config file was found, then create some
41
        # default sections on the config variable.
42 1
        self.config.read(self.config_file)
43 1
        self.check_sections(self.config)
44
45 1
        self.set_env_or_defaults()
46
47 1
        if not os.path.exists(self.config_file):
48 1
            LOG.warning("Config file %s not found.", self.config_file)
49 1
            LOG.warning("Creating a new empty config file.")
50 1
            with open(self.config_file, 'w') as output_file:
51 1
                os.chmod(self.config_file, 0o0600)
52 1
                self.config.write(output_file)
53
54 1
    def log_configs(self):
55
        """Log the read configs if debug is enabled."""
56
        for sec in self.config.sections():
57
            LOG.debug('   %s: %s', sec, self.config.options(sec))
58
59 1
    def set_env_or_defaults(self):
60
        """Read some environment variables and set them on the config.
61
62
        If no environment variable is found and the config section/key is
63
        empty, then set some default values.
64
        """
65 1
        option = namedtuple('Option', ['section', 'name', 'env_var',
66
                                       'default_value'])
67
68 1
        options = [option('auth', 'user', 'NAPPS_USER', None),
69
                   option('auth', 'token', 'NAPPS_TOKEN', None),
70
                   option('napps', 'api', 'NAPPS_API_URI',
71
                          'https://napps.kytos.io/api/'),
72
                   option('napps', 'repo', 'NAPPS_REPO_URI',
73
                          'https://napps.kytos.io/repo'),
74
                   option('kytos', 'api', 'KYTOS_API',
75
                          'http://localhost:8181/')]
76
77 1
        for option in options:
78 1
            if not self.config.has_option(option.section, option.name):
79 1
                env_value = os.environ.get(option.env_var,
80
                                           option.default_value)
81 1
                if env_value:
82 1
                    self.config.set(option.section, option.name, env_value)
83
84 1
        self.config.set('global', 'debug', str(self.debug))
85
86 1
    @staticmethod
87
    def check_sections(config):
88
        """Create a empty config file."""
89 1
        default_sections = ['global', 'auth', 'napps', 'kytos']
90 1
        for section in default_sections:
91 1
            if not config.has_section(section):
92 1
                config.add_section(section)
93
94 1
    def save_token(self, user, token):
95
        """Save the token on the config file."""
96
        self.config.set('auth', 'user', user)
97
        self.config.set('auth', 'token', token)
98
        # allow_no_value=True is used to keep the comments on the config file.
99
        new_config = ConfigParser(allow_no_value=True)
100
101
        # Parse the config file. If no config file was found, then create some
102
        # default sections on the config variable.
103
        new_config.read(self.config_file)
104
        self.check_sections(new_config)
105
106
        new_config.set('auth', 'user', user)
107
        new_config.set('auth', 'token', token)
108
        filename = os.path.expanduser(self.config_file)
109
        with open(filename, 'w') as out_file:
110
            os.chmod(filename, 0o0600)
111
            new_config.write(out_file)
112
113 1
    def clear_token(self):
114
        """Clear Token information on config file."""
115
        # allow_no_value=True is used to keep the comments on the config file.
116
        new_config = ConfigParser(allow_no_value=True)
117
118
        # Parse the config file. If no config file was found, then create some
119
        # default sections on the config variable.
120
        new_config.read(self.config_file)
121
        self.check_sections(new_config)
122
123
        new_config.remove_option('auth', 'user')
124
        new_config.remove_option('auth', 'token')
125
        filename = os.path.expanduser(self.config_file)
126
        with open(filename, 'w') as out_file:
127
            os.chmod(filename, 0o0600)
128
            new_config.write(out_file)
129
130 1
    @classmethod
131
    def get_metadata(cls):
132
        """Return kytos-utils metadata."""
133
        meta_path = ("%s/metadata.py" % os.path.dirname(__file__))
134
        meta_file = open(meta_path).read()
135
        metadata = dict(re.findall(r"(__[a-z]+__)\s*=\s*'([^']+)'", meta_file))
136
        return metadata
137
138 1
    @classmethod
139
    def get_remote_metadata(cls):
140
        """Return kytos metadata."""
141
        kytos_api = KytosConfig().config.get('kytos', 'api')
142
        meta_uri = kytos_api + 'api/kytos/core/metadata/'
143
        meta_file = urllib.request.urlopen(meta_uri).read()
144
        metadata = json.loads(meta_file)
145
        return metadata
146
147 1
    @classmethod
148
    def check_versions(cls):
149
        """Check if kytos and kytos-utils metadata are compatible."""
150
        kytos_metadata = cls.get_remote_metadata()
151
        kutils_metadata = cls.get_metadata()
152
        kytos_version = kytos_metadata.get('__version__')
153
        kutils_version = kutils_metadata.get('__version__')
154
155
        if kytos_version != kutils_version:
156
            logger = logging.getLogger()
157
            logger.warning('kytos (%s) and kytos utils (%s) versions '
158
                           'are not equal.', kytos_version, kutils_version)
159