Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / management / pprint.py @ d5a4a8d1

History | View | Annotate | Download (7.7 kB)

1
#Copyright (C) 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
import sys
35
from snf_django.management.utils import pprint_table
36
from synnefo.lib.ordereddict import OrderedDict
37
from snf_django.lib.astakos import UserCache
38
from synnefo.settings import (CYCLADES_SERVICE_TOKEN as ASTAKOS_TOKEN,
39
                              ASTAKOS_BASE_URL)
40
from synnefo.db.models import Backend, pooled_rapi_client
41
from synnefo.logic.rapi import GanetiApiError
42
from synnefo.logic.reconciliation import nics_from_instance
43

    
44

    
45
def pprint_network(network, display_mails=False, stdout=None, title=None):
46
    if stdout is None:
47
        stdout = sys.stdout
48
    if title is None:
49
        title = "State of Network %s in DB" % network.id
50

    
51
    ucache = UserCache(ASTAKOS_BASE_URL, ASTAKOS_TOKEN)
52
    userid = network.userid
53

    
54
    db_network = OrderedDict([
55
        ("name", network.name),
56
        ("backend-name", network.backend_id),
57
        ("state", network.state),
58
        ("userid", userid),
59
        ("username", ucache.get_name(userid) if display_mails else userid),
60
        ("public", network.public),
61
        ("floating_ip_pool", network.floating_ip_pool),
62
        ("external_router", network.external_router),
63
        ("drained", network.drained),
64
        ("MAC prefix", network.mac_prefix),
65
        ("flavor", network.flavor),
66
        ("link", network.link),
67
        ("mode", network.mode),
68
        ("deleted", network.deleted),
69
        ("tags", "), ".join(network.backend_tag)),
70
        ("action", network.action)])
71

    
72
    pprint_table(stdout, db_network.items(), None, separator=" | ",
73
                 title=title)
74

    
75

    
76
def pprint_network_subnets(network, stdout=None, title=None):
77
    if stdout is None:
78
        stdout = sys.stdout
79
    if title is None:
80
        title = "Subnets of network %s" % network.id
81

    
82
    subnets = list(network.subnets.values_list("id", "name", "ipversion",
83
                                               "cidr", "gateway", "dhcp",
84
                                               "deleted"))
85
    headers = ["ID", "Name", "Version", "CIDR", "Gateway", "DHCP",
86
               "Deleted"]
87
    pprint_table(stdout, subnets, headers, separator=" | ",
88
                 title=title)
89

    
90

    
91
def pprint_network_backends(network, stdout=None, title=None):
92
    if stdout is None:
93
        stdout = sys.stdout
94
    if title is None:
95
        title = "State of Network %s in DB for each backend" % network.id
96
    bnets = list(network.backend_networks.values_list(
97
        "backend__clustername",
98
        "operstate", "deleted", "backendjobid",
99
        "backendopcode", "backendjobstatus"))
100
    headers = ["Backend", "State", "Deleted", "JobID", "Opcode",
101
               "JobStatus"]
102
    pprint_table(stdout, bnets, headers, separator=" | ",
103
                 title=title)
104

    
105

    
106
def pprint_network_in_ganeti(network, stdout=None):
107
    if stdout is None:
108
        stdout = sys.stdout
109
    for backend in Backend.objects.exclude(offline=True):
110
        with pooled_rapi_client(backend) as client:
111
            try:
112
                g_net = client.GetNetwork(network.backend_id)
113
                ip_map = g_net.pop("map")
114
                pprint_table(stdout, g_net.items(), None,
115
                             title="State of network in backend: %s" %
116
                                   backend.clustername)
117
                pprint_pool(None, ip_map, 80, stdout)
118
            except GanetiApiError as e:
119
                if e.code == 404:
120
                    stdout.write('Network does not exist in backend %s\n' %
121
                                 backend.clustername)
122
                else:
123
                    raise e
124

    
125

    
126
def pool_map_chunks(smap, step=64):
127
    for i in xrange(0, len(smap), step):
128
        yield smap[i:i + step]
129

    
130

    
131
def splitPoolMap(s, count):
132
    chunks = pool_map_chunks(s, count)
133
    acc = []
134
    count = 0
135
    for chunk in chunks:
136
        chunk_len = len(chunk)
137
        acc.append(str(count).rjust(3) + ' ' + chunk + ' ' +
138
                   str(count + chunk_len - 1).ljust(4))
139
        count += chunk_len
140
    return '\n' + '\n'.join(acc)
141

    
142

    
143
def pprint_pool(name, pool_map, step=80, stdout=None):
144
    if stdout is None:
145
        stdout = sys.stdout
146
    if name is not None:
147
        stdout.write("Pool: %s\n" % name)
148
    stdout.write(splitPoolMap(pool_map, count=step))
149
    stdout.write("\n")
150

    
151

    
152
def pprint_port(port, stdout=None, title=None):
153
    if stdout is None:
154
        stdout = sys.stdout
155
    if title is None:
156
        title = "State of Port %s in DB" % port.id
157
    port = OrderedDict([
158
        ("id", port.id),
159
        ("name", port.name),
160
        ("userid", port.userid),
161
        ("server", port.machine_id),
162
        ("network", port.network_id),
163
        ("device_owner", port.device_owner),
164
        ("mac", port.mac),
165
        ("state", port.state)])
166

    
167
    pprint_table(stdout, port.items(), None, separator=" | ",
168
                 title=title)
169

    
170

    
171
def pprint_port_ips(port, stdout=None, title=None):
172
    if stdout is None:
173
        stdout = sys.stdout
174
    if title is None:
175
        title = "IP Addresses of Port %s" % port.id
176
    ips = list(port.ips.values_list("address", "network_id", "subnet_id",
177
                                    "subnet__cidr", "floating_ip"))
178
    headers = ["Address", "Network", "Subnet", "CIDR", "is_floating"]
179
    pprint_table(stdout, ips, headers, separator=" | ",
180
                 title=title)
181

    
182

    
183
def pprint_port_in_ganeti(port, stdout=None, title=None):
184
    if stdout is None:
185
        stdout = sys.stdout
186
    if title is None:
187
        title = "State of Port %s in Ganeti" % port.id
188

    
189
    vm = port.machine
190
    if vm is None:
191
        stdout.write("Port is not attached to any instance.\n")
192
        return
193

    
194
    client = vm.get_client()
195
    try:
196
        vm_info = client.GetInstance(vm.backend_vm_id)
197
    except GanetiApiError as e:
198
        if e.code == 404:
199
            stdout.write("NIC seems attached to server %s, but"
200
                         " server does not exist in backend.\n"
201
                         % vm)
202
            return
203
        raise e
204

    
205
    nics = nics_from_instance(vm_info)
206
    try:
207
        gnt_nic = filter(lambda nic: nic.get("name") == port.backend_uuid,
208
                         nics)[0]
209
        gnt_nic["instance"] = vm_info["name"]
210
    except IndexError:
211
        stdout.write("NIC %s is not attached to instance %s" % (port, vm))
212
        return
213
    pprint_table(stdout, gnt_nic.items(), None, separator=" | ",
214
                 title=title)
215

    
216
    vm.put_client(client)