Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (6.5 kB)

1
# Copyright 2013-2014 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
import json
35
import string
36

    
37
from optparse import make_option
38

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

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

    
45

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

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

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

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

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

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

    
111

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

    
115

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

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

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

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

    
139
    networks = stats.get("networks")
140
    if networks is not None:
141
        public_ips = networks.pop("public_ips")
142
        networks["total_public_ips"] = public_ips.get("total", 0)
143
        networks["free_public_ips"] = public_ips.get("free", 0)
144
        fields = ["total", "ACTIVE", "DELETED", "ERROR", "total_public_ips",
145
                  "free_public_ips"]
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, resource)
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()