summaryrefslogtreecommitdiff
path: root/tuskar_ui/utils/utils.py
blob: 8921d09b951534b14b3fa86fac885b42760bd22f (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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# -*- coding: utf8 -*-
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
import base64
import csv
from itertools import izip
import os
import re
import struct
import time

from django.utils.translation import ugettext_lazy as _

CAMEL_RE = re.compile(r'([A-Z][a-z]+|[A-Z]+(?=[A-Z\s]|$))')


def de_camel_case(text):
    """Convert CamelCase names to human-readable format."""
    return ' '.join(w.strip() for w in CAMEL_RE.split(text) if w.strip())


def list_to_dict(object_list, key_attribute='id'):
    """Converts an object list to a dict

    :param object_list: list of objects to be put into a dict
    :type  object_list: list

    :param key_attribute: object attribute used as index by dict
    :type  key_attribute: str

    :return: dict containing the objects in the list
    :rtype: dict
    """
    return dict((getattr(o, key_attribute), o) for o in object_list)


def length(iterator):
    """A length function for iterators

    Returns the number of items in the specified iterator. Note that this
    function consumes the iterator in the process.
    """
    return sum(1 for _item in iterator)


def check_image_type(image, type):
    """Check if image 'type' property matches passed-in type.

    If image has no 'type' property' return True, as we cannot
    be sure what type of image it is.
    """

    return (image.properties.get('type', type) == type)


def filter_items(items, **kwargs):
    """Filters the list of items and returns the filtered list.

    Example usage:
    >>> class Item(object):
    ...     def __init__(self, index):
    ...         self.index = index
    ...     def __repr__(self):
    ...         return '<Item index=%d>' % self.index
    >>> items = [Item(i) for i in range(7)]
    >>> list(filter_items(items, index=1))
    [<Item index=1>]
    >>> list(filter_items(items, index__in=(1, 2, 3)))
    [<Item index=1>, <Item index=2>, <Item index=3>]
    >>> list(filter_items(items, index__not_in=(1, 2, 3)))
    [<Item index=0>, <Item index=4>, <Item index=5>, <Item index=6>]
    """
    for item in items:
        for name, value in kwargs.items():
            if name.endswith('__in'):
                if getattr(item, name[:-len('__in')]) not in value:
                    break
            elif name.endswith('__not_in'):
                if getattr(item, name[:-len('__not_in')]) in value:
                    break
            else:
                if getattr(item, name) != value:
                    break
        else:
            yield item


def safe_int_cast(value):
    try:
        return int(value)
    except (TypeError, ValueError):
        return 0


def parse_csv_file(csv_file):
    """Parses given CSV file.

    If there is no error, it returns list of dicts. When something went wrong,
    list is empty, but warning contains appropriate information about
    possible problems.
    """

    parsed_data = []

    for row in csv.reader(csv_file):
        try:
            driver = row[0].strip()
        except IndexError:
            raise ValueError(_("Unable to parse the CSV file."))

        if driver in ('pxe_ssh', 'pxe_ipmitool'):
            node_keys = (
                'mac_addresses', 'cpu_arch', 'cpus', 'memory_mb', 'local_gb')

            if driver == 'pxe_ssh':
                driver_keys = (
                    'driver', 'ssh_address', 'ssh_username',
                    'ssh_key_contents'
                )

            elif driver == 'pxe_ipmitool':
                driver_keys = (
                    'driver', 'ipmi_address', 'ipmi_username',
                    'ipmi_password'
                )

            node = dict(izip(driver_keys+node_keys, row))

            parsed_data.append(node)

        else:
            raise ValueError(_("Unknown driver: %s.") % driver)

    return parsed_data


def create_cephx_key():
    # NOTE(gfidente): Taken from
    # https://github.com/ceph/ceph-deploy/blob/master/ceph_deploy/new.py#L21
    key = os.urandom(16)
    header = struct.pack("<hiih", 1, int(time.time()), 0, len(key))
    return base64.b64encode(header + key)