Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / logic / management / commands / network-inspect.py @ 18c4414d

History | View | Annotate | Download (5.3 kB)

1
# Copyright 2012 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

    
36
from optparse import make_option
37

    
38
from django.core.management.base import BaseCommand, CommandError
39
from synnefo.management.common import get_network, Omit
40

    
41
from synnefo.db.models import (Backend, BackendNetwork,
42
                               pooled_rapi_client)
43
from synnefo.logic.rapi import GanetiApiError
44
from snf_django.lib.astakos import UserCache
45
from synnefo.settings import (CYCLADES_SERVICE_TOKEN as ASTAKOS_TOKEN,
46
                              ASTAKOS_BASE_URL)
47
from util import pool_map_chunks
48

    
49

    
50
class Command(BaseCommand):
51
    help = "Inspect a network on DB and Ganeti."
52

    
53
    option_list = BaseCommand.option_list + (
54
        make_option(
55
            '--displayname',
56
            action='store_true',
57
            dest='displayname',
58
            default=False,
59
            help="Display both uuid and display name"),
60
    )
61

    
62
    def handle(self, *args, **options):
63
        write = self.stdout.write
64
        if len(args) != 1:
65
            raise CommandError("Please provide a network ID.")
66

    
67
        net = get_network(args[0])
68

    
69
        ucache = UserCache(ASTAKOS_BASE_URL, ASTAKOS_TOKEN)
70

    
71
        displayname = options['displayname']
72

    
73
        sep = '-' * 80 + '\n'
74
        labels = filter(lambda x: x is not Omit,
75
                        ['name', 'backend-name', 'state', 'owner uuid',
76
                         'owner_name' if displayname else Omit, 'subnet',
77
                         'gateway', 'mac_prefix', 'link', 'public', 'dhcp',
78
                         'flavor', 'deleted', 'action', 'pool'])
79

    
80
        uuid = net.userid
81
        if displayname:
82
            dname = ucache.get_name(uuid)
83

    
84
        fields = filter(lambda x: x is not Omit,
85
                        [net.name, net.backend_id, net.state, uuid or '-',
86
                         dname or '-' if displayname else Omit,
87
                         str(net.subnet), str(net.gateway),
88
                         str(net.mac_prefix),
89
                         str(net.link), str(net.public),  str(net.dhcp),
90
                         str(net.flavor), str(net.deleted), str(net.action),
91
                         str(splitPoolMap(net.get_pool().to_map(), 64))])
92

    
93
        write(sep)
94
        write('State of Network in DB\n')
95
        write(sep)
96
        for l, f in zip(labels, fields):
97
            write(l.ljust(20) + ': ' + f.ljust(20) + '\n')
98

    
99
        labels = ('Backend', 'State', 'Deleted', 'JobID', 'OpCode',
100
                  'JobStatus')
101
        for back_net in BackendNetwork.objects.filter(network=net):
102
            write('\n')
103
            fields = (back_net.backend.clustername, back_net.operstate,
104
                      str(back_net.deleted),  str(back_net.backendjobid),
105
                      str(back_net.backendopcode),
106
                      str(back_net.backendjobstatus))
107
            for l, f in zip(labels, fields):
108
                write(l.ljust(20) + ': ' + f.ljust(20) + '\n')
109
        write('\n')
110

    
111
        write(sep)
112
        write('State of Network in Ganeti\n')
113
        write(sep)
114

    
115
        for backend in Backend.objects.exclude(offline=True):
116
            with pooled_rapi_client(backend) as client:
117
                try:
118
                    g_net = client.GetNetwork(net.backend_id)
119
                    write("Backend: %s\n" % backend.clustername)
120
                    print json.dumps(g_net, indent=2)
121
                    write(sep)
122
                except GanetiApiError as e:
123
                    if e.code == 404:
124
                        write('Network does not exist in backend %s\n' %
125
                              backend.clustername)
126
                    else:
127
                        raise e
128

    
129

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