Skip to content

Commit fbd3366

Browse files
committed
Add create endpoint of transit ip addresses
1 parent 5031fa1 commit fbd3366

10 files changed

Lines changed: 178 additions & 1 deletion

File tree

doc/source/sdk/guides/privatenat.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,12 @@ the output with query parameters.
181181

182182
.. literalinclude:: ../examples/natv3/list_private_transit_ips.py
183183
:lines: 16-23
184+
185+
Create Private Transit IP Address
186+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
187+
188+
This interface is used to assign a transit IP address.
189+
:class:`~otcextensions.sdk.natv3.v3.transit_ip.PrivateTransitIp`.
190+
191+
.. literalinclude:: ../examples/natv3/create_private_transit_ip.py
192+
:lines: 16-28

doc/source/sdk/proxies/privatenat.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ Private NAT Gateway Operations
1616

1717
.. autoclass:: otcextensions.sdk.natv3.v3._proxy.Proxy
1818
:noindex:
19-
:members: private_nat_gateways, get_private_nat_gateway, private_dnat_rules, create_private_dnat_rule, update_private_dnat_rule, delete_private_dnat_rule, private_snat_rules, create_private_snat_rule, update_private_snat_rule, delete_private_snat_rule, private_transit_ips
19+
:members: private_nat_gateways, get_private_nat_gateway, private_dnat_rules, create_private_dnat_rule, update_private_dnat_rule, delete_private_dnat_rule, private_snat_rules, create_private_snat_rule, update_private_snat_rule, delete_private_snat_rule, private_transit_ips, create_private_transit_ip
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env python3
2+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
3+
# not use this file except in compliance with the License. You may obtain
4+
# a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11+
# License for the specific language governing permissions and limitations
12+
# under the License.
13+
"""
14+
Assign a private transit IP address.
15+
"""
16+
17+
import openstack
18+
19+
openstack.enable_logging(True)
20+
conn = openstack.connect(cloud="otc")
21+
22+
transit_ip = conn.natv3.create_private_transit_ip(
23+
virsubnet_id="2759da7b-8015-404c-ae0a-a389007b0e2a",
24+
ip_address="192.168.1.68",
25+
enterprise_project_id="2759da7b-8015-404c-ae0a-a389007b0e2a",
26+
tags=[{"key": "key1", "value": "value1"}],
27+
)
28+
print(transit_ip)

otcextensions/osclient/privatenat/v3/transit_ip.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,18 @@
1717
from osc_lib import utils
1818
from osc_lib.command import command
1919

20+
from otcextensions.common import sdk_utils
21+
from otcextensions.common.utils import normalize_tags
2022
from otcextensions.i18n import _
2123

2224
LOG = logging.getLogger(__name__)
2325

2426

27+
def _get_columns(item):
28+
column_map = {}
29+
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)
30+
31+
2532
class ListPrivateTransitIps(command.Lister):
2633

2734
_description = _("List private transit IP addresses.")
@@ -176,3 +183,60 @@ def take_action(self, parsed_args):
176183
for t in data
177184
),
178185
)
186+
187+
188+
class CreatePrivateTransitIp(command.ShowOne):
189+
_description = _("Assign a private transit IP address.")
190+
191+
def get_parser(self, prog_name):
192+
parser = super(CreatePrivateTransitIp, self).get_parser(prog_name)
193+
parser.add_argument(
194+
"--virsubnet-id",
195+
metavar="<virsubnet_id>",
196+
required=True,
197+
help=_("Specifies the subnet ID of the current project."),
198+
)
199+
parser.add_argument(
200+
"--ip-address",
201+
metavar="<ip_address>",
202+
help=_("Specifies the transit IP address."),
203+
)
204+
parser.add_argument(
205+
"--enterprise-project-id",
206+
metavar="<enterprise_project_id>",
207+
help=_(
208+
"Specifies the enterprise project ID associated with the "
209+
"transit IP address."
210+
),
211+
)
212+
parser.add_argument(
213+
"--tags",
214+
metavar="<tags>",
215+
action="append",
216+
help=_(
217+
"Specifies the tag list in KEY=VALUE format. "
218+
"Repeat for multiple values."
219+
),
220+
)
221+
return parser
222+
223+
def take_action(self, parsed_args):
224+
client = self.app.client_manager.privatenat
225+
226+
attrs = {
227+
"virsubnet_id": parsed_args.virsubnet_id,
228+
}
229+
230+
if parsed_args.ip_address:
231+
attrs["ip_address"] = parsed_args.ip_address
232+
if parsed_args.enterprise_project_id:
233+
attrs["enterprise_project_id"] = parsed_args.enterprise_project_id
234+
if parsed_args.tags:
235+
attrs["tags"] = normalize_tags(parsed_args.tags)
236+
237+
obj = client.create_private_transit_ip(**attrs)
238+
239+
display_columns, columns = _get_columns(obj)
240+
data = utils.get_item_properties(obj, columns)
241+
242+
return display_columns, data

otcextensions/sdk/natv3/v3/_proxy.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,16 @@ def private_transit_ips(self, **query):
251251
:class:`~otcextensions.sdk.natv3.v3.transit_ip.PrivateTransitIp`
252252
"""
253253
return self._list(_transit_ip.PrivateTransitIp, **query)
254+
255+
def create_private_transit_ip(self, **attrs):
256+
"""Assign a private NAT transit IP address.
257+
258+
:param dict attrs: Keyword arguments which will be used to assign
259+
a :class:`~otcextensions.sdk.natv3.v3.transit_ip.PrivateTransitIp`,
260+
comprised of the properties on the PrivateTransitIp class.
261+
262+
:returns: The assigned private transit IP address.
263+
264+
:rtype: :class:`~otcextensions.sdk.natv3.v3.transit_ip.PrivateTransitIp`
265+
"""
266+
return self._create(_transit_ip.PrivateTransitIp, **attrs)

otcextensions/sdk/natv3/v3/transit_ip.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class PrivateTransitIp(resource.Resource):
2424

2525
# capabilities
2626
allow_list = True
27+
allow_create = True
2728

2829
_query_mapping = resource.QueryParameters(
2930
"limit",

otcextensions/tests/unit/osclient/privatenat/v3/test_transit_ip.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,58 @@ def test_list_with_supported_filters(self):
128128
)
129129
self.assertEqual(self.columns, columns)
130130
self.assertEqual(self.data, list(data))
131+
132+
133+
class TestCreatePrivateTransitIp(fakes.TestPrivateNat):
134+
_data = fakes.FakePrivateTransitIp.create_one()
135+
136+
def setUp(self):
137+
super(TestCreatePrivateTransitIp, self).setUp()
138+
self.cmd = transit_ip.CreatePrivateTransitIp(self.app, None)
139+
self.client.create_private_transit_ip = mock.Mock(return_value=self._data)
140+
141+
def test_create(self):
142+
arglist = [
143+
"--virsubnet-id",
144+
self._data.virsubnet_id,
145+
"--ip-address",
146+
self._data.ip_address,
147+
"--enterprise-project-id",
148+
self._data.enterprise_project_id,
149+
"--tags",
150+
"key1=value1",
151+
]
152+
verifylist = [
153+
("virsubnet_id", self._data.virsubnet_id),
154+
("ip_address", self._data.ip_address),
155+
("enterprise_project_id", self._data.enterprise_project_id),
156+
("tags", ["key1=value1"]),
157+
]
158+
159+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
160+
columns, data = self.cmd.take_action(parsed_args)
161+
162+
self.client.create_private_transit_ip.assert_called_once_with(
163+
virsubnet_id=self._data.virsubnet_id,
164+
ip_address=self._data.ip_address,
165+
enterprise_project_id=self._data.enterprise_project_id,
166+
tags=[{"key": "key1", "value": "value1"}],
167+
)
168+
self.assertEqual(len(columns), len(data))
169+
self.assertIn("id", columns)
170+
171+
def test_create_minimal(self):
172+
arglist = [
173+
"--virsubnet-id",
174+
self._data.virsubnet_id,
175+
]
176+
verifylist = [
177+
("virsubnet_id", self._data.virsubnet_id),
178+
]
179+
180+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
181+
self.cmd.take_action(parsed_args)
182+
183+
self.client.create_private_transit_ip.assert_called_once_with(
184+
virsubnet_id=self._data.virsubnet_id,
185+
)

otcextensions/tests/unit/sdk/natv3/v3/test_proxy.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,8 @@ class TestPrivateTransitIp(TestNatv3Proxy):
8888

8989
def test_private_transit_ips(self):
9090
self.verify_list(self.proxy.private_transit_ips, transit_ip.PrivateTransitIp)
91+
92+
def test_create_private_transit_ip(self):
93+
self.verify_create(
94+
self.proxy.create_private_transit_ip, transit_ip.PrivateTransitIp
95+
)

otcextensions/tests/unit/sdk/natv3/v3/test_transit_ip.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ def test_basic(self):
4242
self.assertEqual("transit_ip", sot.resource_key)
4343
self.assertEqual("transit_ips", sot.resources_key)
4444
self.assertEqual("/private-nat/transit-ips", sot.base_path)
45+
self.assertTrue(sot.allow_create)
4546
self.assertTrue(sot.allow_list)
4647

4748
def test_make_it(self):

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ openstack.privatenat.v3 =
197197
privatenat_dnat_rule_update = otcextensions.osclient.privatenat.v3.dnat:UpdatePrivateDnatRule
198198
privatenat_dnat_rule_delete = otcextensions.osclient.privatenat.v3.dnat:DeletePrivateDnatRule
199199
privatenat_transit_ip_list = otcextensions.osclient.privatenat.v3.transit_ip:ListPrivateTransitIps
200+
privatenat_transit_ip_create = otcextensions.osclient.privatenat.v3.transit_ip:CreatePrivateTransitIp
200201

201202
openstack.auto_scaling.v1 =
202203
as_group_list = otcextensions.osclient.auto_scaling.v1.group:ListAutoScalingGroup

0 commit comments

Comments
 (0)