Revision d5a4a8d1

b/snf-cyclades-app/synnefo/api/management/commands/network-create.py
39 39

  
40 40
from synnefo.db.models import Network, Backend
41 41
from synnefo.logic import networks
42
from synnefo.management import pprint
42 43

  
43 44
NETWORK_FLAVORS = Network.FLAVORS.keys()
44 45

  
......
194 195
                                  floating_ip_pool=floating_ip_pool,
195 196
                                  backends=backends, lazy_create=False)
196 197

  
197
        self.stdout.write("Created network '%s' in DB.\n" % network)
198
        self.stdout.write("Created network '%s' in DB:\n" % network)
199
        pprint.pprint_network(network, stdout=self.stdout)
200
        pprint.pprint_network_subnets(network, stdout=self.stdout)
b/snf-cyclades-app/synnefo/api/management/commands/port-create.py
37 37
from synnefo.management.common import convert_api_faults
38 38

  
39 39
from synnefo.api import util
40
from synnefo.management.common import (get_network, get_vm,
41
                                       get_floating_ip_by_id)
40
from synnefo.management import common, pprint
42 41
from synnefo.logic import ports
43 42

  
44 43
HELP_MSG = """Create a new port.
......
111 110

  
112 111
        if server_id:
113 112
            owner = "vm"
114
            vm = get_vm(server_id)
113
            vm = common.get_vm(server_id)
115 114
            #if vm.router:
116 115
            #    raise CommandError("Server '%s' does not exist." % server_id)
117 116
        elif router_id:
118 117
            owner = "router"
119
            vm = get_vm(router_id)
118
            vm = common.get_vm(router_id)
120 119
            if not vm.router:
121 120
                raise CommandError("Router '%s' does not exist." % router_id)
122 121
        else:
......
124 123

  
125 124
        floating_ip = None
126 125
        if floating_ip_id:
127
            floating_ip = get_floating_ip_by_id(floating_ip_id,
128
                                                for_update=True)
126
            floating_ip = common.get_floating_ip_by_id(floating_ip_id,
127
                                                       for_update=True)
129 128
            if floating_ip.userid != vm.userid:
130 129
                msg = "Floating IP %s does not belong to server/router owner."
131 130
                raise CommandError(msg % floating_ip)
132 131

  
133 132
        # get the network
134
        network = get_network(network_id)
133
        network = common.get_network(network_id)
135 134

  
136 135
        # validate security groups
137 136
        sg_list = []
......
144 143
        new_port = ports.create(network, vm, name=name, ipaddress=floating_ip,
145 144
                                security_groups=sg_list,
146 145
                                device_owner=owner)
147
        self.stdout.write("Created port '%s' in DB.\n" % new_port)
146
        self.stdout.write("Created port '%s' in DB:\n" % new_port)
147
        pprint.pprint_port(new_port, stdout=self.stdout)
148
        pprint.pprint_port_ips(new_port, stdout=self.stdout)
148 149
        # TODO: Display port information, like ip address
149 150
        # TODO: Add --wait argument to report progress about the Ganeti job.
b/snf-cyclades-app/synnefo/api/management/commands/port-inspect.py
1
# Copyright 2012 GRNET S.A. All rights reserved.
1
# Copyright 2013 GRNET S.A. All rights reserved.
2 2
#
3 3
# Redistribution and use in source and binary forms, with or
4 4
# without modification, are permitted provided that the following
......
34 34
from optparse import make_option
35 35
from django.core.management.base import BaseCommand, CommandError
36 36

  
37
from synnefo.logic.rapi import GanetiApiError
38 37
from synnefo.management.common import convert_api_faults
39
from synnefo.logic.reconciliation import nics_from_instance
40
from snf_django.management.utils import pprint_table
41 38
from synnefo.api.util import get_port
39
from synnefo.management import pprint
42 40

  
43 41

  
44 42
class Command(BaseCommand):
......
67 65

  
68 66
        port = get_port(args[0], None)
69 67

  
70
        db_nic = {
71
            "id": port.id,
72
            "name": port.name,
73
            "userid": port.userid,
74
            "server": port.machine_id,
75
            "network": port.network_id,
76
            "device_owner": port.device_owner,
77
            "mac": port.mac,
78
            "state": port.state}
79

  
80
        pprint_table(self.stdout, db_nic.items(), None, separator=" | ",
81
                     title="State of port in DB")
68
        pprint.pprint_port(port, stdout=self.stdout)
82 69
        self.stdout.write('\n\n')
83 70

  
84
        ips = list(port.ips.values_list("address", "network_id", "subnet_id",
85
                                        "subnet__cidr", "floating_ip"))
86
        headers = ["Address", "Network", "Subnet", "CIDR", "is_floating"]
87
        pprint_table(self.stdout, ips, headers, separator=" | ",
88
                     title="IP Addresses")
71
        pprint.pprint_port_ips(port, stdout=self.stdout)
89 72
        self.stdout.write('\n\n')
90 73

  
91
        vm = port.machine
92
        if vm is None:
93
            self.stdout.write("Port is not attached to any instance.\n")
94
            return
95

  
96
        client = vm.get_client()
97
        try:
98
            vm_info = client.GetInstance(vm.backend_vm_id)
99
        except GanetiApiError as e:
100
            if e.code == 404:
101
                self.stdout.write("NIC seems attached to server %s, but"
102
                                  " server does not exist in backend.\n"
103
                                  % vm)
104
                return
105
            raise e
106

  
107
        nics = nics_from_instance(vm_info)
108
        try:
109
            gnt_nic = filter(lambda nic: nic.get("name") == port.backend_uuid,
110
                             nics)[0]
111
        except IndexError:
112
            self.stdout.write("NIC %s is not attached to instance %s"
113
                              % (port, vm))
114
            return
115
        pprint_table(self.stdout, gnt_nic.items(), None, separator=" | ",
116
                     title="State of port in Ganeti")
117

  
118
        vm.put_client(client)
74
        pprint.pprint_port_in_ganeti(port, stdout=self.stdout)
b/snf-cyclades-app/synnefo/logic/management/commands/network-inspect.py
34 34
from optparse import make_option
35 35

  
36 36
from django.core.management.base import BaseCommand, CommandError
37
from synnefo.management.common import get_network
38

  
39
from synnefo.db.models import (Backend, pooled_rapi_client)
40
from synnefo.logic.rapi import GanetiApiError
41
from snf_django.lib.astakos import UserCache
42
from synnefo.settings import (CYCLADES_SERVICE_TOKEN as ASTAKOS_TOKEN,
43
                              ASTAKOS_BASE_URL)
44
from util import pool_map_chunks
45
from snf_django.management.utils import pprint_table
46
from synnefo.lib.ordereddict import OrderedDict
37
from synnefo.management import pprint, common
47 38

  
48 39

  
49 40
class Command(BaseCommand):
......
59 50
    )
60 51

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

  
66
        network = get_network(args[0])
67

  
68
        ucache = UserCache(ASTAKOS_BASE_URL, ASTAKOS_TOKEN)
69

  
56
        network = common.get_network(args[0])
70 57
        displayname = options['displayname']
71 58

  
72
        userid = network.userid
73
        db_network = OrderedDict([
74
            ("name", network.name),
75
            ("backend-name", network.backend_id),
76
            ("state", network.state),
77
            ("userid", userid),
78
            ("username", ucache.get_name(userid) if displayname else ""),
79
            ("public", network.public),
80
            ("floating_ip_pool", network.floating_ip_pool),
81
            ("external_router", network.external_router),
82
            ("drained", network.drained),
83
            ("MAC prefix", network.mac_prefix),
84
            ("flavor", network.flavor),
85
            ("link", network.link),
86
            ("mode", network.mode),
87
            ("deleted", network.deleted),
88
            ("tags", "), ".join(network.backend_tag)),
89
            ("action", network.action)])
90

  
91
        pprint_table(self.stdout, db_network.items(), None, separator=" | ",
92
                     title="State of Network in DB")
93

  
94
        subnets = list(network.subnets.values_list("id", "name", "ipversion",
95
                                                   "cidr", "gateway", "dhcp",
96
                                                   "deleted"))
97
        headers = ["ID", "Name", "Version", "CIDR", "Gateway", "DHCP",
98
                   "Deleted"]
99
        write("\n\n")
100
        pprint_table(self.stdout, subnets, headers, separator=" | ",
101
                     title="Subnets")
102

  
103
        bnets = list(network.backend_networks.values_list(
104
            "backend__clustername",
105
            "operstate", "deleted", "backendjobid",
106
            "backendopcode", "backendjobstatus"))
107
        headers = ["Backend", "State", "Deleted", "JobID", "Opcode",
108
                   "JobStatus"]
109
        write("\n\n")
110
        pprint_table(self.stdout, bnets, headers, separator=" | ",
111
                     title="Backend Networks")
112

  
113
        write("\n\n")
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(network.backend_id)
119
                    ip_map = g_net.pop("map")
120
                    pprint_table(self.stdout, g_net.items(), None,
121
                                 title="State of network in backend: %s" %
122
                                       backend.clustername)
123
                    write(splitPoolMap(ip_map, 80) + "\n\n")
124
                except GanetiApiError as e:
125
                    if e.code == 404:
126
                        write('Network does not exist in backend %s\n' %
127
                              backend.clustername)
128
                    else:
129
                        raise e
130

  
131

  
132
def splitPoolMap(s, count):
133
    chunks = pool_map_chunks(s, count)
134
    acc = []
135
    count = 0
136
    for chunk in chunks:
137
        chunk_len = len(chunk)
138
        acc.append(str(count).rjust(3) + ' ' + chunk + ' ' +
139
                   str(count + chunk_len - 1).ljust(4))
140
        count += chunk_len
141
    return '\n' + '\n'.join(acc)
59
        pprint.pprint_network(network, display_mails=displayname,
60
                              stdout=self.stdout)
61
        self.stdout.write("\n\n")
62
        pprint.pprint_network_subnets(network, stdout=self.stdout)
63
        self.stdout.write("\n\n")
64
        pprint.pprint_network_backends(network, stdout=self.stdout)
65
        self.stdout.write("\n\n")
66
        pprint.pprint_network_in_ganeti(network, stdout=self.stdout)
b/snf-cyclades-app/synnefo/logic/management/commands/pool-show.py
34 34
from django.core.management.base import BaseCommand, CommandError
35 35
from optparse import make_option
36 36

  
37
from util import pool_table_from_type, pool_map_chunks
38 37
from synnefo.db.pools import bitarray_to_map
38
from synnefo.db.models import MacPrefixPoolTable, BridgePoolTable
39
from synnefo.management import pprint
39 40

  
40 41
POOL_CHOICES = ['bridge', 'mac-prefix']
41 42

  
......
81 82
            self.stdout.write(line.encode('utf8'))
82 83

  
83 84
        step = (type_ == 'bridge') and 64 or 80
84
        print_map('Pool', pool.to_map(), step, self.stdout)
85
        print_map('Reserved', bitarray_to_map(pool.reserved[:pool_row.size]),
86
                  step, self.stdout)
85
        pprint.pprint_pool('Available', pool.to_map(), step, self.stdout)
86
        pprint.pprint_pool('Reserved',
87
                           bitarray_to_map(pool.reserved[:pool_row.size]),
88
                           step, self.stdout)
87 89

  
88 90

  
89
def print_map(name, pool_map, step, out):
90
    sep = '*' * 80
91
    out.write(sep + "\n")
92
    out.write("%s: \n" % name)
93
    out.write(sep + "\n")
94
    count = 0
95
    for chunk in pool_map_chunks(pool_map, step):
96
        chunk_len = len(chunk)
97
        out.write(("%s " % count).rjust(4))
98
        out.write((chunk + " %d\n") % (count + chunk_len - 1))
99
        count += chunk_len
91
def pool_table_from_type(type_):
92
    if type_ == "mac-prefix":
93
        return MacPrefixPoolTable
94
    elif type_ == "bridge":
95
        return BridgePoolTable
96
    # elif type == "ip":
97
    #     return IPPoolTable
98
    else:
99
        raise ValueError("Invalid pool type")
/dev/null
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
from synnefo.db.models import MacPrefixPoolTable, BridgePoolTable
35

  
36

  
37
def pool_table_from_type(type_):
38
    if type_ == "mac-prefix":
39
        return MacPrefixPoolTable
40
    elif type_ == "bridge":
41
        return BridgePoolTable
42
    # elif type == "ip":
43
    #     return IPPoolTable
44
    else:
45
        raise ValueError("Invalid pool type")
46

  
47

  
48
def pool_map_chunks(smap, step=64):
49
    for i in xrange(0, len(smap), step):
50
        yield smap[i:i + step]
b/snf-cyclades-app/synnefo/management/pprint.py
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)

Also available in: Unified diff