Skip to content

Commit d828b04

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Support Neutron Address Group CRUD"
2 parents 8993d32 + f57e10b commit d828b04

7 files changed

Lines changed: 1075 additions & 0 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
=============
2+
address group
3+
=============
4+
5+
An **address group** is a group of IPv4 or IPv6 address blocks which could be
6+
referenced as a remote source or destination when creating a security group
7+
rule.
8+
9+
Network v2
10+
11+
.. autoprogram-cliff:: openstack.network.v2
12+
:command: address group *
Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
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+
"""Address group action implementations"""
15+
16+
import logging
17+
18+
import netaddr
19+
from osc_lib.command import command
20+
from osc_lib import exceptions
21+
from osc_lib import utils
22+
23+
from openstackclient.i18n import _
24+
from openstackclient.identity import common as identity_common
25+
from openstackclient.network import sdk_utils
26+
27+
28+
LOG = logging.getLogger(__name__)
29+
30+
31+
def _get_columns(item):
32+
column_map = {
33+
'tenant_id': 'project_id',
34+
}
35+
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)
36+
37+
38+
def _format_addresses(addresses):
39+
ret = []
40+
for addr in addresses:
41+
ret.append(str(netaddr.IPNetwork(addr)))
42+
return ret
43+
44+
45+
def _get_attrs(client_manager, parsed_args):
46+
attrs = {}
47+
attrs['name'] = parsed_args.name
48+
if parsed_args.description:
49+
attrs['description'] = parsed_args.description
50+
attrs['addresses'] = _format_addresses(parsed_args.address)
51+
if 'project' in parsed_args and parsed_args.project is not None:
52+
identity_client = client_manager.identity
53+
project_id = identity_common.find_project(
54+
identity_client,
55+
parsed_args.project,
56+
parsed_args.project_domain,
57+
).id
58+
attrs['tenant_id'] = project_id
59+
60+
return attrs
61+
62+
63+
class CreateAddressGroup(command.ShowOne):
64+
_description = _("Create a new Address Group")
65+
66+
def get_parser(self, prog_name):
67+
parser = super(CreateAddressGroup, self).get_parser(prog_name)
68+
parser.add_argument(
69+
'name',
70+
metavar="<name>",
71+
help=_("New address group name")
72+
)
73+
parser.add_argument(
74+
'--description',
75+
metavar="<description>",
76+
help=_("New address group description")
77+
)
78+
parser.add_argument(
79+
"--address",
80+
metavar="<ip-address>",
81+
action='append',
82+
default=[],
83+
help=_("IP address or CIDR "
84+
"(repeat option to set multiple addresses)"),
85+
)
86+
parser.add_argument(
87+
'--project',
88+
metavar="<project>",
89+
help=_("Owner's project (name or ID)")
90+
)
91+
identity_common.add_project_domain_option_to_parser(parser)
92+
93+
return parser
94+
95+
def take_action(self, parsed_args):
96+
client = self.app.client_manager.network
97+
attrs = _get_attrs(self.app.client_manager, parsed_args)
98+
99+
obj = client.create_address_group(**attrs)
100+
display_columns, columns = _get_columns(obj)
101+
data = utils.get_item_properties(obj, columns, formatters={})
102+
103+
return (display_columns, data)
104+
105+
106+
class DeleteAddressGroup(command.Command):
107+
_description = _("Delete address group(s)")
108+
109+
def get_parser(self, prog_name):
110+
parser = super(DeleteAddressGroup, self).get_parser(prog_name)
111+
parser.add_argument(
112+
'address_group',
113+
metavar="<address-group>",
114+
nargs='+',
115+
help=_("Address group(s) to delete (name or ID)")
116+
)
117+
118+
return parser
119+
120+
def take_action(self, parsed_args):
121+
client = self.app.client_manager.network
122+
result = 0
123+
124+
for group in parsed_args.address_group:
125+
try:
126+
obj = client.find_address_group(group, ignore_missing=False)
127+
client.delete_address_group(obj)
128+
except Exception as e:
129+
result += 1
130+
LOG.error(_("Failed to delete address group with "
131+
"name or ID '%(group)s': %(e)s"),
132+
{'group': group, 'e': e})
133+
134+
if result > 0:
135+
total = len(parsed_args.address_group)
136+
msg = (_("%(result)s of %(total)s address groups failed "
137+
"to delete.") % {'result': result, 'total': total})
138+
raise exceptions.CommandError(msg)
139+
140+
141+
class ListAddressGroup(command.Lister):
142+
_description = _("List address groups")
143+
144+
def get_parser(self, prog_name):
145+
parser = super(ListAddressGroup, self).get_parser(prog_name)
146+
147+
parser.add_argument(
148+
'--name',
149+
metavar='<name>',
150+
help=_("List only address groups of given name in output")
151+
)
152+
parser.add_argument(
153+
'--project',
154+
metavar="<project>",
155+
help=_("List address groups according to their project "
156+
"(name or ID)")
157+
)
158+
identity_common.add_project_domain_option_to_parser(parser)
159+
160+
return parser
161+
162+
def take_action(self, parsed_args):
163+
client = self.app.client_manager.network
164+
columns = (
165+
'id',
166+
'name',
167+
'description',
168+
'project_id',
169+
'addresses',
170+
)
171+
column_headers = (
172+
'ID',
173+
'Name',
174+
'Description',
175+
'Project',
176+
'Addresses',
177+
)
178+
attrs = {}
179+
if parsed_args.name:
180+
attrs['name'] = parsed_args.name
181+
if 'project' in parsed_args and parsed_args.project is not None:
182+
identity_client = self.app.client_manager.identity
183+
project_id = identity_common.find_project(
184+
identity_client,
185+
parsed_args.project,
186+
parsed_args.project_domain,
187+
).id
188+
attrs['tenant_id'] = project_id
189+
attrs['project_id'] = project_id
190+
data = client.address_groups(**attrs)
191+
192+
return (column_headers,
193+
(utils.get_item_properties(
194+
s, columns, formatters={},
195+
) for s in data))
196+
197+
198+
class SetAddressGroup(command.Command):
199+
_description = _("Set address group properties")
200+
201+
def get_parser(self, prog_name):
202+
parser = super(SetAddressGroup, self).get_parser(prog_name)
203+
parser.add_argument(
204+
'address_group',
205+
metavar="<address-group>",
206+
help=_("Address group to modify (name or ID)")
207+
)
208+
parser.add_argument(
209+
'--name',
210+
metavar="<name>",
211+
help=_('Set address group name')
212+
)
213+
parser.add_argument(
214+
'--description',
215+
metavar="<description>",
216+
help=_('Set address group description')
217+
)
218+
parser.add_argument(
219+
"--address",
220+
metavar="<ip-address>",
221+
action='append',
222+
default=[],
223+
help=_("IP address or CIDR "
224+
"(repeat option to set multiple addresses)"),
225+
)
226+
return parser
227+
228+
def take_action(self, parsed_args):
229+
client = self.app.client_manager.network
230+
obj = client.find_address_group(
231+
parsed_args.address_group,
232+
ignore_missing=False)
233+
attrs = {}
234+
if parsed_args.name is not None:
235+
attrs['name'] = parsed_args.name
236+
if parsed_args.description is not None:
237+
attrs['description'] = parsed_args.description
238+
if attrs:
239+
client.update_address_group(obj, **attrs)
240+
if parsed_args.address:
241+
client.add_addresses_to_address_group(
242+
obj, _format_addresses(parsed_args.address))
243+
244+
245+
class ShowAddressGroup(command.ShowOne):
246+
_description = _("Display address group details")
247+
248+
def get_parser(self, prog_name):
249+
parser = super(ShowAddressGroup, self).get_parser(prog_name)
250+
parser.add_argument(
251+
'address_group',
252+
metavar="<address-group>",
253+
help=_("Address group to display (name or ID)")
254+
)
255+
256+
return parser
257+
258+
def take_action(self, parsed_args):
259+
client = self.app.client_manager.network
260+
obj = client.find_address_group(
261+
parsed_args.address_group,
262+
ignore_missing=False)
263+
display_columns, columns = _get_columns(obj)
264+
data = utils.get_item_properties(obj, columns, formatters={})
265+
266+
return (display_columns, data)
267+
268+
269+
class UnsetAddressGroup(command.Command):
270+
_description = _("Unset address group properties")
271+
272+
def get_parser(self, prog_name):
273+
parser = super(UnsetAddressGroup, self).get_parser(prog_name)
274+
parser.add_argument(
275+
'address_group',
276+
metavar="<address-group>",
277+
help=_("Address group to modify (name or ID)")
278+
)
279+
parser.add_argument(
280+
"--address",
281+
metavar="<ip-address>",
282+
action='append',
283+
default=[],
284+
help=_("IP address or CIDR "
285+
"(repeat option to unset multiple addresses)"),
286+
)
287+
return parser
288+
289+
def take_action(self, parsed_args):
290+
client = self.app.client_manager.network
291+
obj = client.find_address_group(
292+
parsed_args.address_group,
293+
ignore_missing=False)
294+
if parsed_args.address:
295+
client.remove_addresses_from_address_group(
296+
obj, _format_addresses(parsed_args.address))

0 commit comments

Comments
 (0)