Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / api / management / commands / port-create.py @ dfbe006a

History | View | Annotate | Download (6.3 kB)

1
# Copyright 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
from optparse import make_option
35

    
36
from django.core.management.base import BaseCommand, CommandError
37

    
38
from synnefo.api import util
39
from synnefo.management import common, pprint
40
from snf_django.management.utils import parse_bool
41
from synnefo.logic import ports
42

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

45
Connect a server/router to a network by creating a new port. If 'floating_ip'
46
option is used, the specified floating IP will be assigned to the new port.
47
Otherwise, the port will get an IP address for each Subnet that is associated
48
with the network."""
49

    
50

    
51
class Command(BaseCommand):
52
    help = HELP_MSG
53

    
54
    option_list = BaseCommand.option_list + (
55
        make_option(
56
            "--name",
57
            dest="name",
58
            default=None,
59
            help="Name of the port."),
60
        make_option(
61
            "--network",
62
            dest="network_id",
63
            default=None,
64
            help="The ID of the network where the port will be created."),
65
        make_option(
66
            "--server",
67
            dest="server_id",
68
            default=None,
69
            help="The ID of the server that the port will be connected to."),
70
        #make_option(
71
        #    "--router",
72
        #    dest="router_id",
73
        #    default=None,
74
        #    help="The ID of the router that the port will be connected to."),
75
        make_option(
76
            "--floating-ip",
77
            dest="floating_ip_id",
78
            default=None,
79
            help="The ID of the floating IP to use for the port."),
80
        make_option(
81
            "--ipv4-address",
82
            dest="ipv4_address",
83
            default=None,
84
            help="Specify IPv4 address for the new port."),
85
        make_option(
86
            "--security-groups",
87
            dest="security-groups",
88
            default=None,
89
            help="Comma separated list of Security Group IDs to associate"
90
                 " with the port."),
91
        make_option(
92
            "--wait",
93
            dest="wait",
94
            default="True",
95
            choices=["True", "False"],
96
            metavar="True|False",
97
            help="Wait for Ganeti jobs to complete."),
98
    )
99

    
100
    @common.convert_api_faults
101
    def handle(self, *args, **options):
102
        if args:
103
            raise CommandError("Command doesn't accept any arguments")
104

    
105
        name = options["name"]
106
        network_id = options["network_id"]
107
        server_id = options["server_id"]
108
        #router_id = options["router_id"]
109
        router_id = None
110
        # assume giving security groups comma separated
111
        security_group_ids = options["security-groups"]
112
        wait = parse_bool(options["wait"])
113

    
114
        if not name:
115
            name = ""
116

    
117
        if (server_id and router_id) or not (server_id or router_id):
118
            raise CommandError("Please give either a server or a router id")
119

    
120
        if not network_id:
121
            raise CommandError("Please specify a 'network'")
122

    
123
        if server_id:
124
            owner = "vm"
125
            vm = common.get_vm(server_id)
126
            #if vm.router:
127
            #    raise CommandError("Server '%s' does not exist." % server_id)
128
        elif router_id:
129
            owner = "router"
130
            vm = common.get_vm(router_id)
131
            if not vm.router:
132
                raise CommandError("Router '%s' does not exist." % router_id)
133
        else:
134
            raise CommandError("Neither server or router is specified")
135

    
136
        # get the network
137
        network = common.get_network(network_id)
138

    
139
        # Get either floating IP or fixed ip address
140
        ipaddress = None
141
        floating_ip_id = options["floating_ip_id"]
142
        ipv4_address = options["ipv4_address"]
143
        if ipv4_address is not None and floating_ip_id is not None:
144
            raise CommandError("Please use either --floating-ip-id or"
145
                               " --ipv4-address option")
146
        elif floating_ip_id:
147
            ipaddress = common.get_floating_ip_by_id(floating_ip_id,
148
                                                     for_update=True)
149
        if ipv4_address is not None:
150
            ipaddress = util.allocate_ip(network, vm.userid,
151
                                         address=ipv4_address)
152

    
153
        # validate security groups
154
        sg_list = []
155
        if security_group_ids:
156
            security_group_ids = security_group_ids.split(",")
157
            for gid in security_group_ids:
158
                sg = util.get_security_group(int(gid))
159
                sg_list.append(sg)
160

    
161
        new_port = ports.create(network, vm, name=name, ipaddress=ipaddress,
162
                                security_groups=sg_list,
163
                                device_owner=owner)
164
        self.stdout.write("Created port '%s' in DB:\n" % new_port)
165
        pprint.pprint_port(new_port, stdout=self.stdout)
166
        pprint.pprint_port_ips(new_port, stdout=self.stdout)
167
        self.stdout.write("\n")
168
        common.wait_server_task(new_port.machine, wait, stdout=self.stdout)