Skip to content

Commit 2853b71

Browse files
authored
Add Private Snat rules list (#650)
Add Private Snat rules list Reviewed-by: Anton Sidelnikov
1 parent 411bcb6 commit 2853b71

16 files changed

Lines changed: 638 additions & 1 deletion

File tree

doc/source/cli/privatenat.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,11 @@ Private NAT Gateway Operations
1717

1818
.. autoprogram-cliff:: openstack.privatenat.v3
1919
:command: privatenat gateway *
20+
21+
.. _private_snat:
22+
23+
Private SNAT Rule Operations
24+
----------------------------
25+
26+
.. autoprogram-cliff:: openstack.privatenat.v3
27+
:command: privatenat snat rule *

doc/source/sdk/guides/privatenat.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,19 @@ This interface is used to delete a specified DNAT rule.
113113

114114
.. literalinclude:: ../examples/natv3/delete_private_dnat_rule.py
115115
:lines: 16-22
116+
117+
SNAT
118+
----
119+
120+
The SNAT function enables servers in a VPC or connected networks to use
121+
transit IP addresses for outbound private address translation.
122+
123+
List Private SNAT Rules
124+
^^^^^^^^^^^^^^^^^^^^^^^
125+
126+
This interface is used to query an SNAT rule list and to filter
127+
the output with query parameters.
128+
:class:`~otcextensions.sdk.natv3.v3.snat.PrivateSnat`.
129+
130+
.. literalinclude:: ../examples/natv3/list_private_snat_rules.py
131+
:lines: 16-23

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
19+
:members: private_nat_gateways, get_private_nat_gateway, private_dnat_rules, private_snat_rules

doc/source/sdk/resources/privatenat/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ Private NAT Resources
66

77
v3/private_gateway
88
v3/private_dnat
9+
v3/private_snat
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
otcextensions.sdk.natv3.v3.snat
2+
===============================
3+
4+
.. automodule:: otcextensions.sdk.natv3.v3.snat
5+
6+
The Private SNAT Rule Class
7+
---------------------------
8+
9+
The ``PrivateSnat`` class inherits from
10+
:class:`~otcextensions.sdk.sdk_resource.Resource`.
11+
12+
.. autoclass:: otcextensions.sdk.natv3.v3.snat.PrivateSnat
13+
:members:
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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+
List all Private SNAT Rules
15+
"""
16+
17+
import openstack
18+
19+
openstack.enable_logging(True)
20+
conn = openstack.connect(cloud="otc")
21+
22+
for snat_rule in conn.natv3.private_snat_rules():
23+
print(snat_rule)
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
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+
"""Private SNAT v3 action implementations"""
14+
15+
import logging
16+
17+
from osc_lib import utils
18+
from osc_lib.command import command
19+
20+
from otcextensions.i18n import _
21+
22+
LOG = logging.getLogger(__name__)
23+
24+
25+
def _get_transit_ip_addresses(rule):
26+
return ", ".join(
27+
association.transit_ip_address
28+
for association in (rule.transit_ip_associations or [])
29+
if getattr(association, "transit_ip_address", None)
30+
)
31+
32+
33+
class ListPrivateSnatRules(command.Lister):
34+
35+
_description = _("List private SNAT rules.")
36+
columns = (
37+
"id",
38+
"gateway_id",
39+
"virsubnet_id",
40+
"cidr",
41+
"transit_ip_addresses",
42+
"description",
43+
"status",
44+
)
45+
46+
def get_parser(self, prog_name):
47+
parser = super(ListPrivateSnatRules, self).get_parser(prog_name)
48+
49+
parser.add_argument(
50+
"--id",
51+
metavar="<id>",
52+
action="append",
53+
help=_("Specifies the SNAT rule ID. Repeat to filter by multiple values."),
54+
)
55+
parser.add_argument(
56+
"--limit",
57+
metavar="<limit>",
58+
type=int,
59+
help=_("Specifies the number of records displayed on each page."),
60+
)
61+
parser.add_argument(
62+
"--marker",
63+
metavar="<marker>",
64+
help=_("Specifies the start resource ID of pagination query."),
65+
)
66+
parser.add_argument(
67+
"--page-reverse",
68+
action="store_true",
69+
help=_("Query resources on the previous page."),
70+
)
71+
parser.add_argument(
72+
"--project-id",
73+
metavar="<project_id>",
74+
action="append",
75+
help=_("Specifies the project ID. Repeat to filter by multiple values."),
76+
)
77+
parser.add_argument(
78+
"--description",
79+
metavar="<description>",
80+
action="append",
81+
help=_(
82+
"Provides supplementary information about the SNAT rule. "
83+
"Repeat to filter by multiple values."
84+
),
85+
)
86+
parser.add_argument(
87+
"--gateway-id",
88+
metavar="<gateway_id>",
89+
action="append",
90+
help=_(
91+
"Specifies the private NAT gateway ID. "
92+
"Repeat to filter by multiple values."
93+
),
94+
)
95+
parser.add_argument(
96+
"--cidr",
97+
metavar="<cidr>",
98+
action="append",
99+
help=_(
100+
"Specifies the CIDR block that matches the SNAT rule. "
101+
"Repeat to filter by multiple values."
102+
),
103+
)
104+
parser.add_argument(
105+
"--virsubnet-id",
106+
metavar="<virsubnet_id>",
107+
action="append",
108+
help=_(
109+
"Specifies the subnet ID that matches the SNAT rule. "
110+
"Repeat to filter by multiple values."
111+
),
112+
)
113+
parser.add_argument(
114+
"--transit-ip-id",
115+
metavar="<transit_ip_id>",
116+
action="append",
117+
help=_(
118+
"Specifies the transit IP address ID. "
119+
"Repeat to filter by multiple values."
120+
),
121+
)
122+
parser.add_argument(
123+
"--transit-ip-address",
124+
metavar="<transit_ip_address>",
125+
action="append",
126+
help=_(
127+
"Specifies the transit IP address. "
128+
"Repeat to filter by multiple values."
129+
),
130+
)
131+
parser.add_argument(
132+
"--enterprise-project-id",
133+
metavar="<enterprise_project_id>",
134+
action="append",
135+
help=_(
136+
"Specifies the enterprise project ID. "
137+
"Repeat to filter by multiple values."
138+
),
139+
)
140+
return parser
141+
142+
def take_action(self, parsed_args):
143+
client = self.app.client_manager.privatenat
144+
145+
args_list = [
146+
"id",
147+
"limit",
148+
"marker",
149+
"page_reverse",
150+
"project_id",
151+
"description",
152+
"gateway_id",
153+
"cidr",
154+
"virsubnet_id",
155+
"transit_ip_id",
156+
"transit_ip_address",
157+
"enterprise_project_id",
158+
]
159+
160+
attrs = {}
161+
for arg in args_list:
162+
val = getattr(parsed_args, arg, None)
163+
164+
if val is None:
165+
continue
166+
if isinstance(val, list) and not val:
167+
continue
168+
if isinstance(val, bool) and not val:
169+
continue
170+
171+
attrs[arg] = val
172+
173+
data = client.private_snat_rules(**attrs)
174+
175+
return (
176+
self.columns,
177+
(
178+
utils.get_dict_properties(
179+
{
180+
"id": s.id,
181+
"gateway_id": s.gateway_id,
182+
"virsubnet_id": s.virsubnet_id,
183+
"cidr": s.cidr,
184+
"transit_ip_addresses": _get_transit_ip_addresses(s),
185+
"description": s.description,
186+
"status": s.status,
187+
},
188+
self.columns,
189+
)
190+
for s in data
191+
),
192+
)

otcextensions/sdk/natv3/v3/_proxy.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from otcextensions.common.utils import extract_url_parts
1414
from otcextensions.sdk.natv3.v3 import dnat as _dnat
1515
from otcextensions.sdk.natv3.v3 import gateway as _gateway
16+
from otcextensions.sdk.natv3.v3 import snat as _snat
1617

1718

1819
class Proxy(proxy.Proxy):
@@ -160,3 +161,21 @@ def delete_private_dnat_rule(self, dnat_rule, ignore_missing=True):
160161
:returns: ``None``
161162
"""
162163
return self._delete(_dnat.PrivateDnat, dnat_rule, ignore_missing=ignore_missing)
164+
165+
# ======== SNAT rules ========
166+
167+
def private_snat_rules(self, **query):
168+
"""Query SNAT rules of a private NAT gateway.
169+
170+
This API is used to query SNAT rules.
171+
172+
:param kwargs query: Optional query parameters to filter the results.
173+
Supported parameters include:
174+
limit, marker, page_reverse, id, project_id,
175+
description, gateway_id, cidr, virsubnet_id,
176+
transit_ip_id, transit_ip_address, enterprise_project_id
177+
178+
:returns: A generator of
179+
:class:`~otcextensions.sdk.natv3.v3.snat.PrivateSnat`
180+
"""
181+
return self._list(_snat.PrivateSnat, **query)

otcextensions/sdk/natv3/v3/snat.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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+
from openstack import resource
14+
15+
16+
class AssociatedTransitIp(resource.Resource):
17+
#: Specifies the transit IP address ID.
18+
transit_ip_id = resource.Body("transit_ip_id")
19+
20+
#: Specifies the transit IP address.
21+
transit_ip_address = resource.Body("transit_ip_address")
22+
23+
24+
class PrivateSnat(resource.Resource):
25+
resources_key = "snat_rules"
26+
resource_key = "snat_rule"
27+
base_path = "/private-nat/snat-rules"
28+
29+
# capabilities
30+
allow_list = True
31+
32+
_query_mapping = resource.QueryParameters(
33+
"limit",
34+
"marker",
35+
"page_reverse",
36+
"id",
37+
"project_id",
38+
"description",
39+
"gateway_id",
40+
"cidr",
41+
"virsubnet_id",
42+
"transit_ip_id",
43+
"transit_ip_address",
44+
"enterprise_project_id",
45+
)
46+
47+
#: Specifies the SNAT rule ID.
48+
id = resource.Body("id")
49+
50+
#: Specifies the project ID.
51+
project_id = resource.Body("project_id")
52+
53+
#: Specifies the private NAT gateway ID.
54+
gateway_id = resource.Body("gateway_id")
55+
56+
#: Specifies the CIDR block that matches the SNAT rule.
57+
cidr = resource.Body("cidr")
58+
59+
#: Specifies the ID of the subnet that matches the SNAT rule.
60+
virsubnet_id = resource.Body("virsubnet_id")
61+
62+
#: Provides supplementary information about the SNAT rule.
63+
description = resource.Body("description")
64+
65+
#: Specifies the list of details of associated transit IP addresses.
66+
transit_ip_associations = resource.Body(
67+
"transit_ip_associations", type=list, list_type=AssociatedTransitIp
68+
)
69+
70+
#: Specifies when the SNAT rule was created.
71+
created_at = resource.Body("created_at")
72+
73+
#: Specifies when the SNAT rule was updated.
74+
updated_at = resource.Body("updated_at")
75+
76+
#: Specifies the enterprise project ID.
77+
enterprise_project_id = resource.Body("enterprise_project_id")
78+
79+
#: Specifies the SNAT rule status.
80+
#: ACTIVE, FROZEN
81+
status = resource.Body("status")

0 commit comments

Comments
 (0)