Skip to content

Commit 8f59524

Browse files
committed
Network CRUD
bp/neutron https://wiki.openstack.org/wiki/OpenStackClient/Commands#Network_2 Change-Id: I89ee083154afa544b03587e84becace36d9d522a
1 parent adf9349 commit 8f59524

14 files changed

Lines changed: 740 additions & 2 deletions

File tree

openstackclient/common/utils.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,16 @@ def format_dict(data):
8484
return output[:-2]
8585

8686

87+
def format_list(data):
88+
"""Return a formatted strings
89+
90+
:param data: a list of strings
91+
:rtype: a string formatted to a,b,c
92+
"""
93+
94+
return ', '.join(data)
95+
96+
8797
def get_item_properties(item, fields, mixed_case_fields=[], formatters={}):
8898
"""Return a tuple containing the item properties.
8999

openstackclient/network/__init__.py

Whitespace-only changes.

openstackclient/network/client.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
#
13+
14+
import logging
15+
16+
from openstackclient.common import utils
17+
18+
19+
LOG = logging.getLogger(__name__)
20+
21+
DEFAULT_NETWORK_API_VERSION = '2.0'
22+
API_VERSION_OPTION = 'os_network_api_version'
23+
API_NAME = "network"
24+
API_VERSIONS = {
25+
"2.0": "neutronclient.v2_0.client.Client",
26+
}
27+
28+
29+
def make_client(instance):
30+
"""Returns an network service client."""
31+
network_client = utils.get_client_class(
32+
API_NAME,
33+
instance._api_version[API_NAME],
34+
API_VERSIONS)
35+
if not instance._url:
36+
instance._url = instance.get_endpoint_for_service_type("network")
37+
return network_client(
38+
username=instance._username,
39+
tenant_name=instance._project_name,
40+
password=instance._password,
41+
region_name=instance._region_name,
42+
auth_url=instance._auth_url,
43+
endpoint_url=instance._url,
44+
token=instance._token,
45+
insecure=instance._insecure,
46+
ca_cert=instance._cacert,
47+
)
48+
49+
50+
def build_option_parser(parser):
51+
"""Hook to add global options"""
52+
parser.add_argument(
53+
'--os-network-api-version',
54+
metavar='<network-api-version>',
55+
default=utils.env(
56+
'OS_NETWORK_API_VERSION',
57+
default=DEFAULT_NETWORK_API_VERSION),
58+
help='Network API version, default=' +
59+
DEFAULT_NETWORK_API_VERSION +
60+
' (Env: OS_NETWORK_API_VERSION)')
61+
return parser

openstackclient/network/common.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
#
13+
14+
from openstackclient.common import exceptions
15+
16+
17+
def find(client, resource, resources, name_or_id):
18+
"""Find a network resource
19+
20+
:param client: network client
21+
:param resource: name of the resource
22+
:param resources: plural name of resource
23+
:param name_or_id: name or id of resource user is looking for
24+
25+
For example:
26+
n = find(netclient, 'network', 'networks', 'matrix')
27+
"""
28+
list_method = getattr(client, "list_%s" % resources)
29+
# Search for by name
30+
data = list_method(name=name_or_id, fields='id')
31+
info = data[resources]
32+
if len(info) == 1:
33+
return info[0]['id']
34+
if len(info) > 1:
35+
msg = "More than one %s exists with the name '%s'."
36+
raise exceptions.CommandError(msg % (resource, name_or_id))
37+
# Search for by id
38+
data = list_method(id=name_or_id, fields='id')
39+
info = data[resources]
40+
if len(info) == 1:
41+
return info[0]['id']
42+
msg = "No %s with a name or ID of '%s' exists." % (resource, name_or_id)
43+
raise exceptions.CommandError(msg)

openstackclient/network/v2_0/__init__.py

Whitespace-only changes.
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
#
13+
14+
"""Network action implementations"""
15+
16+
import logging
17+
import six
18+
19+
from cliff import command
20+
from cliff import lister
21+
from cliff import show
22+
23+
from openstackclient.common import exceptions
24+
from openstackclient.common import utils
25+
from openstackclient.network import common
26+
27+
28+
def filters(data):
29+
if 'subnets' in data:
30+
data['subnets'] = utils.format_list(data['subnets'])
31+
return data
32+
33+
34+
class CreateNetwork(show.ShowOne):
35+
"""Create a network"""
36+
37+
log = logging.getLogger(__name__ + '.CreateNetwork')
38+
39+
def get_parser(self, prog_name):
40+
parser = super(CreateNetwork, self).get_parser(prog_name)
41+
parser.add_argument(
42+
'name', metavar='<network_name>',
43+
help='Name of network to create')
44+
admin_group = parser.add_mutually_exclusive_group()
45+
admin_group.add_argument(
46+
'--admin-state-up',
47+
dest='admin_state', action='store_true',
48+
default=True, help='Set Admin State Up')
49+
admin_group.add_argument(
50+
'--admin-state-down',
51+
dest='admin_state', action='store_false',
52+
help='Set Admin State Down')
53+
share_group = parser.add_mutually_exclusive_group()
54+
share_group.add_argument(
55+
'--share',
56+
dest='shared', action='store_true',
57+
default=None,
58+
help='Share the network across tenants')
59+
share_group.add_argument(
60+
'--no-share',
61+
dest='shared', action='store_false',
62+
help='Do not share the network across tenants')
63+
return parser
64+
65+
def take_action(self, parsed_args):
66+
self.log.debug('take_action(%s)' % parsed_args)
67+
client = self.app.client_manager.network
68+
body = self.get_body(parsed_args)
69+
create_method = getattr(client, "create_network")
70+
data = create_method(body)['network']
71+
if data:
72+
data = filters(data)
73+
else:
74+
data = {'': ''}
75+
return zip(*sorted(six.iteritems(data)))
76+
77+
def get_body(self, parsed_args):
78+
body = {'name': str(parsed_args.name),
79+
'admin_state_up': parsed_args.admin_state}
80+
if parsed_args.shared is not None:
81+
body['shared'] = parsed_args.shared
82+
return {'network': body}
83+
84+
85+
class DeleteNetwork(command.Command):
86+
87+
log = logging.getLogger(__name__ + '.DeleteNetwork')
88+
89+
def get_parser(self, prog_name):
90+
parser = super(DeleteNetwork, self).get_parser(prog_name)
91+
parser.add_argument(
92+
'identifier',
93+
metavar="<network>",
94+
help=("Name or identifier of network to delete")
95+
)
96+
return parser
97+
98+
def take_action(self, parsed_args):
99+
self.log.debug('take_action(%s)' % parsed_args)
100+
client = self.app.client_manager.network
101+
_id = common.find(client, 'network', 'networks',
102+
parsed_args.identifier)
103+
delete_method = getattr(client, "delete_network")
104+
delete_method(_id)
105+
return
106+
107+
108+
class ListNetwork(lister.Lister):
109+
"""List networks"""
110+
111+
log = logging.getLogger(__name__ + '.ListNetwork')
112+
113+
def get_parser(self, prog_name):
114+
parser = super(ListNetwork, self).get_parser(prog_name)
115+
parser.add_argument(
116+
'--external',
117+
action='store_true',
118+
default=False,
119+
help='List external networks',
120+
)
121+
parser.add_argument(
122+
'--dhcp',
123+
help='ID of the DHCP agent')
124+
parser.add_argument(
125+
'--long',
126+
action='store_true',
127+
default=False,
128+
help='Long listing',
129+
)
130+
return parser
131+
132+
def take_action(self, parsed_args):
133+
self.log.debug('take_action(%s)' % parsed_args)
134+
client = self.app.client_manager.network
135+
if parsed_args.dhcp:
136+
list_method = getattr(client, 'list_networks_on_dhcp_agent')
137+
resources = 'networks_on_dhcp_agent'
138+
report_filter = {'dhcp_agent': parsed_args.dhcp}
139+
data = list_method(**report_filter)[resources]
140+
else:
141+
list_method = getattr(client, "list_networks")
142+
report_filter = {}
143+
if parsed_args.external:
144+
report_filter = {'router:external': True}
145+
data = list_method(**report_filter)['networks']
146+
columns = len(data) > 0 and sorted(data[0].keys()) or []
147+
if parsed_args.columns:
148+
list_columns = parsed_args.columns
149+
else:
150+
list_columns = ['id', 'name', 'subnets']
151+
if not parsed_args.long and not parsed_args.dhcp:
152+
columns = [x for x in list_columns if x in columns]
153+
formatters = {'subnets': utils.format_list}
154+
return (columns,
155+
(utils.get_dict_properties(s, columns, formatters=formatters)
156+
for s in data))
157+
158+
159+
class SetNetwork(command.Command):
160+
161+
log = logging.getLogger(__name__ + '.SetNetwork')
162+
163+
def get_parser(self, prog_name):
164+
parser = super(SetNetwork, self).get_parser(prog_name)
165+
parser.add_argument(
166+
'identifier',
167+
metavar="<network>",
168+
help=("Name or identifier of network to set")
169+
)
170+
admin_group = parser.add_mutually_exclusive_group()
171+
admin_group.add_argument(
172+
'--admin-state-up',
173+
dest='admin_state', action='store_true',
174+
default=None,
175+
help='Set Admin State Up')
176+
admin_group.add_argument(
177+
'--admin-state-down',
178+
dest='admin_state', action='store_false',
179+
help='Set Admin State Down')
180+
parser.add_argument(
181+
'--name',
182+
metavar='<network_name>',
183+
help='New name for the network')
184+
share_group = parser.add_mutually_exclusive_group()
185+
share_group.add_argument(
186+
'--share',
187+
dest='shared', action='store_true',
188+
default=None,
189+
help='Share the network across tenants')
190+
share_group.add_argument(
191+
'--no-share',
192+
dest='shared', action='store_false',
193+
help='Do not share the network across tenants')
194+
return parser
195+
196+
def take_action(self, parsed_args):
197+
self.log.debug('take_action(%s)' % parsed_args)
198+
client = self.app.client_manager.network
199+
_id = common.find(client, 'network', 'networks',
200+
parsed_args.identifier)
201+
body = {}
202+
if parsed_args.name is not None:
203+
body['name'] = str(parsed_args.name)
204+
if parsed_args.admin_state is not None:
205+
body['admin_state_up'] = parsed_args.admin_state
206+
if parsed_args.shared is not None:
207+
body['shared'] = parsed_args.shared
208+
if body == {}:
209+
raise exceptions.CommandError("Nothing specified to be set")
210+
update_method = getattr(client, "update_network")
211+
update_method(_id, {'network': body})
212+
return
213+
214+
215+
class ShowNetwork(show.ShowOne):
216+
217+
log = logging.getLogger(__name__ + '.ShowNetwork')
218+
219+
def get_parser(self, prog_name):
220+
parser = super(ShowNetwork, self).get_parser(prog_name)
221+
parser.add_argument(
222+
'identifier',
223+
metavar="<network>",
224+
help=("Name or identifier of network to show")
225+
)
226+
return parser
227+
228+
def take_action(self, parsed_args):
229+
self.log.debug('take_action(%s)' % parsed_args)
230+
client = self.app.client_manager.network
231+
_id = common.find(client, 'network', 'networks',
232+
parsed_args.identifier)
233+
show_method = getattr(client, "show_network")
234+
data = show_method(_id)['network']
235+
data = filters(data)
236+
return zip(*sorted(six.iteritems(data)))

openstackclient/tests/fakes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def __init__(self):
5252
self.image = None
5353
self.object = None
5454
self.volume = None
55+
self.network = None
5556
self.auth_ref = None
5657

5758

openstackclient/tests/network/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)