Revision 86961519

b/snf-cyclades-app/synnefo/api/management/commands/port-inspect.py
31 31
# interpreted as representing official policies, either expressed
32 32
# or implied, of GRNET S.A.
33 33

  
34
from datetime import datetime
35 34
from optparse import make_option
36 35
from django.core.management.base import BaseCommand, CommandError
37 36

  
38
from synnefo.lib.utils import merge_time
39
from snf_django.lib.astakos import UserCache
40 37
from synnefo.logic.rapi import GanetiApiError
41
from synnefo.management.common import Omit, convert_api_faults
42
from synnefo.management import common
43
from synnefo.settings import (CYCLADES_SERVICE_TOKEN as ASTAKOS_TOKEN,
44
                              ASTAKOS_BASE_URL)
45

  
38
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
46 41
from synnefo.api.util import get_port
42

  
43

  
47 44
class Command(BaseCommand):
48 45
    help = "Inspect a port on DB and Ganeti"
49 46
    args = "<port ID>"
......
71 68
        port = get_port(args[0], None)
72 69

  
73 70
        sep = '-' * 80 + '\n'
74
        labels =  ['name',  'id', 'device_id', 'network_id',
75
                   'device_owner', 'mac_address', 'ipv4', 'subnet4',
76
                   'ipv6', 'subnet6', 'state',
77
                   'security_groups', 'user_id']
78

  
79
        uuid = port.userid
80
        security_groups = port.security_groups.values_list('id',
81
                                                                 flat=True)
82
        sg_csv = ','.join(map(str, security_groups))
83

  
84
        ipv4 = ''
85
        ipv6 = ''
86
        subnet4 = ''
87
        subnet6 = ''
88
        for ip in port.ips.all():
89
            if ip.subnet.ipversion == 4:
90
                ipv4 = ip.address
91
                subnet4 = str(ip.subnet.id)
92
            else:
93
                ipv6 = ip.address
94
                subnet6 = str(ip.subnet.id)
95

  
96
        fields = [port.name, str(port.id), str(port.machine.id),
97
                  str(port.network.id), port.device_owner, port.mac,
98
                  ipv4, subnet4, ipv6, subnet6, port.state, sg_csv, uuid]
71

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

  
100 82
        self.stdout.write(sep)
101 83
        self.stdout.write('State of port in DB\n')
102 84
        self.stdout.write(sep)
103
        for l, f in zip(labels, fields):
104
            if f:
105
                self.stdout.write(l.ljust(18) + ': ' + f.ljust(20) + '\n')
106
            else:
107
                self.stdout.write(l.ljust(18) + ': ' + '\n')
108

  
109
        self.stdout.write('\n')
110
        '''
85
        pprint_table(self.stdout, db_nic.items(), None, separator=" | ")
86

  
87
        self.stdout.write('\n\n')
88
        ips = list(port.ips.values_list("address", "network_id", "subnet_id",
89
                                        "subnet__cidr", "floating_ip"))
90
        headers = ["Address", "Network", "Subnet", "CIDR", "is_floating"]
91
        pprint_table(self.stdout, ips, headers, separator=" | ")
92

  
93
        self.stdout.write('\n\n')
94

  
95
        self.stdout.write(sep)
96
        self.stdout.write('State of port in Ganeti\n')
97
        self.stdout.write(sep)
98
        vm = port.machine
99
        if vm is None:
100
            self.stdout.write("Port is not attached to any instance.\n")
101
            return
102

  
111 103
        client = vm.get_client()
112 104
        try:
113
            g_vm = client.GetInstance(vm.backend_vm_id)
114
            self.stdout.write('\n')
115
            self.stdout.write(sep)
116
            self.stdout.write('State of Server in Ganeti\n')
117
            self.stdout.write(sep)
118
            for i in GANETI_INSTANCE_FIELDS:
119
                try:
120
                    value = g_vm[i]
121
                    if i.find('time') != -1:
122
                        value = datetime.fromtimestamp(value)
123
                    self.stdout.write(i.ljust(14) + ': ' + str(value) + '\n')
124
                except KeyError:
125
                    pass
105
            vm_info = client.GetInstance(vm.backend_vm_id)
126 106
        except GanetiApiError as e:
127 107
            if e.code == 404:
128
                self.stdout.write('Server does not exist in backend %s\n' %
129
                                  vm.backend.clustername)
130
            else:
131
                raise e
108
                self.stdout.write("NIC seems attached to server %s, but"
109
                                  " server does not exist in backend.\n"
110
                                  % vm)
132 111

  
133
        if not options['jobs']:
112
        nics = nics_from_instance(vm_info)
113
        try:
114
            gnt_nic = filter(lambda nic: nic.get("name") == port.backend_uuid,
115
                             nics)[0]
116
        except IndexError:
117
            self.stdout.write("NIC %s is not attached to instance %s"
118
                              % (port, vm))
134 119
            return
120
        pprint_table(self.stdout, gnt_nic.items(), None, separator=" | ")
135 121

  
136
        self.stdout.write('\n')
137
        self.stdout.write(sep)
138
        self.stdout.write('Non-archived jobs concerning Server in Ganeti\n')
139
        self.stdout.write(sep)
140
        jobs = client.GetJobs()
141
        for j in jobs:
142
            info = client.GetJobStatus(j)
143
            summary = ' '.join(info['summary'])
144
            job_is_relevant = summary.startswith("INSTANCE") and\
145
                (summary.find(vm.backend_vm_id) != -1)
146
            if job_is_relevant:
147
                for i in GANETI_JOB_FIELDS:
148
                    value = info[i]
149
                    if i.find('_ts') != -1:
150
                        value = merge_time(value)
151
                    try:
152
                        self.stdout.write(i.ljust(14) + ': ' + str(value) +
153
                                          '\n')
154
                    except KeyError:
155
                        pass
156
                self.stdout.write('\n' + sep)
157
        # Return the RAPI client to pool
158 122
        vm.put_client(client)
159
        '''
b/snf-cyclades-app/synnefo/api/management/commands/port-list.py
31 31
# interpreted as representing official policies, either expressed
32 32
# or implied, of GRNET S.A.
33 33

  
34
from optparse import make_option
34
#from optparse import make_option
35 35

  
36 36
from snf_django.management.commands import ListCommand
37 37
from synnefo.db.models import NetworkInterface
......
45 45
class Command(ListCommand):
46 46
    help = "List ports"
47 47

  
48

  
49 48
    object_class = NetworkInterface
50 49
    user_uuid_field = "userid"
51 50
    astakos_url = ASTAKOS_BASE_URL
......
54 53
    def get_fixed_ips(ip):
55 54

  
56 55
        def labels((a, b)):
57
            return str({"subnet": b, "ip_address": str(a) })
56
            return str({"subnet": b, "ip_address": str(a)})
58 57

  
59 58
        lista = ip.get_ip_addresses_subnets()
60 59
        lista = map(labels, lista)
......
66 65
        "user.uuid": ("userid", "The UUID of the port's owner"),
67 66
        "mac_address": ("mac", "The MAC address of the port"),
68 67
        "device_id": ("machine.id", "The vm's id the port is conncted to"),
69
        "status": ("status", "The port's status"),
68
        "state": ("state", "The port's status"),
70 69
        "device_owner": ("device_owner", "The owner of the port (vm/router)"),
71 70
        "network": ("network.id", "The network's ID the port is\
72 71
                        connected to"),
......
77 76
    }
78 77

  
79 78
    fields = ["id", "name", "user.uuid", "mac_address", "network",
80
               "device_id", "fixed_ips"]
79
              "device_id", "fixed_ips", "state"]
b/snf-cyclades-app/synnefo/api/ports.py
31 31
# interpreted as representing official policies, either expressed
32 32
# or implied, of GRNET S.A.
33 33

  
34
from django.conf import settings
34
#from django.conf import settings
35 35
from django.conf.urls import patterns
36 36
from django.http import HttpResponse
37 37
from django.utils import simplejson as json
......
41 41
from snf_django.lib import api
42 42

  
43 43
from synnefo.api import util
44
from synnefo.db.models import NetworkInterface, SecurityGroup, IPAddress
44
from synnefo.db.models import NetworkInterface
45 45
from synnefo.logic import ports
46 46

  
47 47
from logging import getLogger
......
81 81
    log.debug('list_ports detail=%s', detail)
82 82

  
83 83
    user_ports = NetworkInterface.objects.filter(
84
        network__userid=request.user_uniq)
84
        machine__userid=request.user_uniq)
85 85

  
86 86
    port_dicts = [port_to_dict(port, detail)
87 87
                  for port in user_ports.order_by('id')]
......
110 110
    if network.public:
111 111
        raise api.faults.Forbidden('forbidden')
112 112

  
113
    vm = util.get_vm(dev_id, user_id)
113
    vm = util.get_vm(dev_id, user_id, non_deleted=True, non_suspended=True)
114 114

  
115 115
    name = api.utils.get_attribute(port_dict, "name", required=False)
116

  
117 116
    if name is None:
118 117
        name = ""
119 118

  
......
179 178
@transaction.commit_on_success
180 179
def delete_port(request, port_id):
181 180
    log.info('delete_port %s', port_id)
182
    port = util.get_port(port_id, request.user_uniq, for_update=True)
183
    '''
184
    FIXME delete the port
185
    skip the backend part...
186
    release the ips associated with the port
187
    '''
181
    user_id = request.user_uniq
182
    port = util.get_port(port_id, user_id, for_update=True)
183
    ports.delete(port)
188 184
    return HttpResponse(status=204)
189 185

  
190 186
#util functions
......
193 189
def port_to_dict(port, detail=True):
194 190
    d = {'id': str(port.id), 'name': port.name}
195 191
    if detail:
196
        d['user_id'] = port.network.userid
197
        d['tenant_id'] = port.network.userid
192
        user_id = port.machine.id
193
        d['user_id'] = user_id
194
        d['tenant_id'] = user_id
198 195
        d['device_id'] = str(port.machine.id)
196
        # TODO: Change this based on the status of VM
199 197
        d['admin_state_up'] = True
200 198
        d['mac_address'] = port.mac
201 199
        d['status'] = port.state
b/snf-cyclades-app/synnefo/logic/ports.py
30 30
# documentation are those of the authors and should not be
31 31
# interpreted as representing official policies, either expressed
32 32
# or implied, of GRNET S.A.
33
import ipaddr
34

  
35 33
from functools import wraps
36 34
from django.db import transaction
37 35

  
38
from django.conf import settings
39
from snf_django.lib.api import faults
36
#from django.conf import settings
40 37
from synnefo.api import util
41
from synnefo import quotas
42
from synnefo.db.models import NetworkInterface, IPAddress
38
from snf_django.lib.api import faults
39
from synnefo.db.models import NetworkInterface
40
from synnefo.logic import backend
43 41

  
44 42
from logging import getLogger
45 43
log = getLogger(__name__)
......
54 52
        return wrapper
55 53
    return decorator
56 54

  
55

  
57 56
@transaction.commit_on_success
58 57
def create(network, machine, name="", security_groups=None,
59 58
           device_owner='vm'):
......
61 60
    if network.state != 'ACTIVE':
62 61
        raise faults.Conflict('Network build in process')
63 62

  
63
    user_id = machine.userid
64 64
    #create the port
65 65
    port = NetworkInterface.objects.create(name=name,
66 66
                                           network=network,
67 67
                                           machine=machine,
68
                                           userid=machine.userid,
68
                                           userid=user_id,
69 69
                                           device_owner=device_owner,
70 70
                                           state="BUILDING")
71 71
    #add the security groups if any
72 72
    if security_groups:
73 73
        port.security_groups.add(*security_groups)
74 74

  
75
    #add new port to every subnet of the network
76
    for subn in network.subnets.all():
77
        IPAddress.objects.create(subnet=subn,
78
                                 network=network,
79
                                 nic=port,
80
                                 userid=machine.userid,
81
                                 # FIXME
82
                                 address="192.168.0." + str(subn.id))
75
    ipaddress = None
76
    if network.subnets.filter(ipversion=4).exists():
77
            ipaddress = util.allocate_ip(network, user_id)
78
            ipaddress.nic = port
79
            ipaddress.save()
80

  
81
    jobID = backend.connect_to_network(machine, port)
82

  
83
    log.info("Created Port %s with IP Address: %s. Job: %s",
84
             port, ipaddress, jobID)
83 85

  
84
    # Issue commission to Quotaholder and accept it since at the end of
85
    # this transaction the Network object will be created in the DB.
86
    # Note: the following call does a commit!
87
    #quotas.issue_and_accept_commission(new_port)
86
    # TODO: Consider quotas for Ports
88 87

  
89 88
    return port
90 89

  
90

  
91 91
@transaction.commit_on_success
92 92
def delete(port):
93
    port.ips.all().delete()
94
    port.delete()
93
    """Delete a port by removing the NIC card the instance.
94

  
95
    Send a Job to remove the NIC card from the instance. The port
96
    will be deleted and the associated IPv4 addressess will be released
97
    when the job completes successfully.
98

  
99
    """
100

  
101
    jobID = backend.disconnect_from_network(port.machine, port)
102
    log.info("Removing port %s, Job: %s", port, jobID)
103
    return port

Also available in: Unified diff