Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / network.py @ 0e27687b

History | View | Annotate | Download (6.9 kB)

1
# Copyright 2011-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 io import StringIO
35
from pydoc import pager
36

    
37
from kamaki.cli import command
38
from kamaki.cli.command_tree import CommandTree
39
from kamaki.cli.errors import CLISyntaxError, CLIBaseUrlError
40
from kamaki.clients.cyclades import CycladesNetworkClient
41
from kamaki.cli.argument import FlagArgument, ValueArgument
42
from kamaki.cli.commands import _command_init, errors, addLogSettings
43
from kamaki.cli.commands import (
44
    _optional_output_cmd, _optional_json, _name_filter, _id_filter)
45

    
46

    
47
network_cmds = CommandTree('network', 'Networking API network commands')
48
port_cmds = CommandTree('port', 'Networking API network commands')
49
subnet_cmds = CommandTree('subnet', 'Networking API network commands')
50
_commands = [network_cmds, port_cmds, subnet_cmds]
51

    
52

    
53
about_authentication = '\nUser Authentication:\
54
    \n* to check authentication: /user authenticate\
55
    \n* to set authentication token: /config set cloud.<cloud>.token <token>'
56

    
57

    
58
class _init_network(_command_init):
59
    @errors.generic.all
60
    @addLogSettings
61
    def _run(self, service='network'):
62
        if getattr(self, 'cloud', None):
63
            base_url = self._custom_url(service) or self._custom_url(
64
                'compute')
65
            if base_url:
66
                token = self._custom_token(service) or self._custom_token(
67
                    'compute') or self.config.get_cloud('token')
68
                self.client = CycladesNetworkClient(
69
                  base_url=base_url, token=token)
70
                return
71
        else:
72
            self.cloud = 'default'
73
        if getattr(self, 'auth_base', False):
74
            cyclades_endpoints = self.auth_base.get_service_endpoints(
75
                self._custom_type('compute') or 'compute',
76
                self._custom_version('compute') or '')
77
            base_url = cyclades_endpoints['publicURL']
78
            token = self.auth_base.token
79
            self.client = CycladesNetworkClient(base_url=base_url, token=token)
80
        else:
81
            raise CLIBaseUrlError(service='network')
82

    
83
    def main(self):
84
        self._run()
85

    
86

    
87
@command(network_cmds)
88
class network_list(_init_network, _optional_json, _name_filter, _id_filter):
89
    """List networks
90
    Use filtering arguments (e.g., --name-like) to manage long server lists
91
    """
92

    
93
    arguments = dict(
94
        detail=FlagArgument('show detailed output', ('-l', '--details')),
95
        more=FlagArgument(
96
            'output results in pages (-n to set items per page, default 10)',
97
            '--more'),
98
    )
99

    
100
    @errors.generic.all
101
    @errors.cyclades.connection
102
    def _run(self):
103
        nets = self.client.list_networks(detail=self['detail'])
104
        nets = self._filter_by_name(nets)
105
        nets = self._filter_by_id(nets)
106
        kwargs = dict()
107
        if self['more']:
108
            kwargs['out'] = StringIO()
109
            kwargs['title'] = ()
110
        self._print(nets, **kwargs)
111
        if self['more']:
112
            pager(kwargs['out'].getvalue())
113

    
114
    def main(self):
115
        super(self.__class__, self)._run()
116
        self._run()
117

    
118

    
119
@command(network_cmds)
120
class network_info(_init_network, _optional_json):
121
    """Get details about a network"""
122

    
123
    @errors.generic.all
124
    @errors.cyclades.connection
125
    @errors.cyclades.network_id
126
    def _run(self, network_id):
127
        net = self.client.get_network_details(network_id)
128
        self._print(net, self.print_dict)
129

    
130
    def main(self, network_id):
131
        super(self.__class__, self)._run()
132
        self._run(network_id=network_id)
133

    
134

    
135
@command(network_cmds)
136
class network_create(_init_network, _optional_json):
137
    """Create a new network
138
    Valid network types: CUSTOM MAC_FILTERED IP_LESS_ROUTED PHYSICAL_VLAN
139
    """
140

    
141
    arguments = dict(
142
        name=ValueArgument('Network name', '--name'),
143
        shared=FlagArgument(
144
            'Make network shared (special privileges required)', '--shared')
145
    )
146

    
147
    @errors.generic.all
148
    @errors.cyclades.connection
149
    @errors.cyclades.network_type
150
    def _run(self, network_type):
151
        net = self.client.create_network(
152
            network_type, name=self['name'], shared=self['shared'])
153
        self._print(net, self.print_dict)
154

    
155
    def main(self, network_type):
156
        super(self.__class__, self)._run()
157
        self._run(network_type=network_type)
158

    
159

    
160
@command(network_cmds)
161
class network_delete(_init_network, _optional_output_cmd):
162
    """Delete a network"""
163

    
164
    @errors.generic.all
165
    @errors.cyclades.connection
166
    @errors.cyclades.network_id
167
    def _run(self, network_id):
168
        r = self.client.delete_network(network_id)
169
        self._optional_output(r)
170

    
171
    def main(self, network_id):
172
        super(self.__class__, self)._run()
173
        self._run(network_id=network_id)
174

    
175

    
176
@command(network_cmds)
177
class network_set(_init_network, _optional_json):
178
    """Set an attribute of a network, leave the rest untouched (update)
179
    Only "--name" is supported for now
180
    """
181

    
182
    arguments = dict(name=ValueArgument('New name of the network', '--name'))
183

    
184
    @errors.generic.all
185
    @errors.cyclades.connection
186
    @errors.cyclades.network_id
187
    def _run(self, network_id):
188
        if self['name'] in (None, ):
189
            raise CLISyntaxError(
190
                'Missing network attributes to update',
191
                details=[
192
                    'At least one if the following is expected:',
193
                    '  --name=<new name>'])
194
        r = self.client.update_network(network_id, name=self['name'])
195
        self._print(r, self.print_dict)
196

    
197
    def main(self, network_id):
198
        super(self.__class__, self)._run()
199
        self._run(network_id=network_id)