Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / logic / management / commands / stats-cyclades.py @ bda47e03

History | View | Annotate | Download (6.4 kB)

1
# Copyright 2013 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34

    
35
import json
36
import string
37

    
38
from optparse import make_option
39

    
40
from snf_django.management.utils import pprint_table, parse_bool
41

    
42
from snf_django.management.commands import SynnefoCommand, CommandError
43
from synnefo.management.common import get_backend
44
from synnefo.admin import stats as statistics
45

    
46

    
47
class Command(SynnefoCommand):
48
    help = "Get available statistics of Cyclades service"
49
    can_import_settings = True
50

    
51
    option_list = SynnefoCommand.option_list + (
52
        make_option("--backend",
53
                    dest="backend",
54
                    help="Include statistics only for this backend."),
55
        make_option("--clusters",
56
                    dest="clusters",
57
                    default="True",
58
                    metavar="True|False",
59
                    choices=["True", "False"],
60
                    help="Include statistics about clusters."),
61
        make_option("--servers",
62
                    dest="servers",
63
                    default="True",
64
                    metavar="True|False",
65
                    choices=["True", "False"],
66
                    help="Include statistics about servers."),
67
        make_option("--resources",
68
                    dest="resources",
69
                    default="True",
70
                    metavar="True|False",
71
                    choices=["True", "False"],
72
                    help="Include statistics about resources "
73
                         " (CPU, RAM, DISK)."),
74
        make_option("--networks",
75
                    dest="networks",
76
                    default="True",
77
                    metavar="True|False",
78
                    choices=["True", "False"],
79
                    help="Include statistics about networks."),
80
        make_option("--images",
81
                    dest="images",
82
                    default="False",
83
                    metavar="True|False",
84
                    choices=["True", "False"],
85
                    help="Include statistics about images."),
86
    )
87

    
88
    def handle(self, *args, **options):
89
        if options["backend"] is not None:
90
            backend = get_backend(options["backend"])
91
        else:
92
            backend = None
93

    
94
        clusters = parse_bool(options["clusters"])
95
        servers = parse_bool(options["servers"])
96
        resources = parse_bool(options["resources"])
97
        networks = parse_bool(options["networks"])
98
        images = parse_bool(options["images"])
99

    
100
        stats = statistics.get_cyclades_stats(backend, clusters, servers,
101
                                              resources, networks, images)
102

    
103
        output_format = options["output_format"]
104
        if output_format == "json":
105
            self.stdout.write(json.dumps(stats, indent=4) + "\n")
106
        elif output_format == "pretty":
107
            pretty_print_stats(stats, self.stdout)
108
        else:
109
            raise CommandError("Output format '%s' not supported." %
110
                               output_format)
111

    
112

    
113
def columns_from_fields(fields, values):
114
    return zip(map(string.lower, fields), [values.get(f, 0) for f in fields])
115

    
116

    
117
def pretty_print_stats(stats, stdout):
118
    newline = lambda: stdout.write("\n")
119

    
120
    _datetime = stats.get("datetime")
121
    stdout.write("datetime: %s\n" % _datetime)
122
    newline()
123

    
124
    clusters = stats.get("clusters")
125
    if clusters is not None:
126
        fields = ["total", "drained", "offline"]
127
        table = columns_from_fields(fields, clusters)
128
        pprint_table(stdout, table, None,
129
                     title="Statistics for Ganeti Clusters")
130
        newline()
131

    
132
    servers = stats.get("servers")
133
    if servers is not None:
134
        fields = ["total", "STARTED", "STOPPED", "BUILD", "ERROR", "DESTROYED"]
135
        table = columns_from_fields(fields, servers)
136
        pprint_table(stdout, table, None,
137
                     title="Statistics for Virtual Servers")
138
        newline()
139

    
140
    networks = stats.get("networks")
141
    if networks is not None:
142
        public_ips = networks.pop("public_ips")
143
        networks["total_public_ips"] = public_ips.get("total", 0)
144
        networks["free_public_ips"] = public_ips.get("free", 0)
145
        fields = ["total", "ACTIVE", "DELETED", "ERROR"]
146
        table = columns_from_fields(fields, networks)
147
        pprint_table(stdout, table, None,
148
                     title="Statistics for Virtual Networks")
149
        newline()
150

    
151
    resources = stats.get("resources")
152
    if resources is not None:
153
        for resource_name, resource in sorted(resources.items()):
154
            fields = ["total", "allocated"]
155
            for res, num in sorted(resource.pop("servers", {}).items()):
156
                name = "servers_with_%s" % res
157
                resource[name] = num
158
                fields.append(name)
159
            table = columns_from_fields(fields, resources)
160
            pprint_table(stdout, table, None,
161
                         title="Statistics for %s" % resource_name)
162
            newline()
163

    
164
    images = stats.get("images")
165
    if images is not None:
166
        pprint_table(stdout, sorted(images.items()), None,
167
                     title="Statistics for Images")
168
        newline()