Skip to content

Commit 31ccae0

Browse files
authored
625 feat vpc version management (#628)
625 feat vpc version management Reviewed-by: Anton Sidelnikov Reviewed-by: Valeriia Ziukina
1 parent 3c2c322 commit 31ccae0

16 files changed

Lines changed: 805 additions & 12 deletions

otcextensions/sdk/apig/v2/_proxy.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
from otcextensions.sdk.apig.v2 import ssl_domain as _ssl_domain
4848
from otcextensions.sdk.apig.v2 import tag as _tag
4949
from otcextensions.sdk.apig.v2 import config as _config
50+
from otcextensions.sdk.apig.v2 import vpc_endpoint as _vpc_endpoint
5051

5152

5253
class Proxy(proxy.Proxy):
@@ -3469,3 +3470,27 @@ def configs_for_gateway(self, gateway_id, **attrs):
34693470
paginated=False,
34703471
base_path=base_path,
34713472
**attrs,)
3473+
3474+
# ======== VPC Endpoint Management Methods ========
3475+
3476+
def vpc_endpoints(self, gateway, **attrs):
3477+
"""List all VPC endpoints
3478+
3479+
This method retrieves all VPC endpoints associated with the specified
3480+
API Gateway instance.
3481+
3482+
:param gateway: The ID or an instance of
3483+
:class:`~otcextensions.sdk.apig.v2.gateway.Gateway`
3484+
:param attrs: Optional query parameters for filtering the list,
3485+
such as limit, offset, id, marker_id, status
3486+
3487+
:returns: A generator of
3488+
:class:`~otcextensions.sdk.apig.v2.vpc_endpoint.VpcEndpoint`
3489+
instances
3490+
"""
3491+
gateway = self._get_resource(_gateway.Gateway, gateway)
3492+
return self._list(
3493+
_vpc_endpoint.VpcEndpoint,
3494+
gateway_id=gateway.id,
3495+
**attrs
3496+
)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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+
from openstack import resource
13+
14+
15+
class VpcEndpoint(resource.Resource):
16+
resources_key = "connections"
17+
base_path = f'apigw/instances/%(gateway_id)s/vpc-endpoint/connections'
18+
19+
_query_mapping = resource.QueryParameters('limit', 'offset', 'id',
20+
'marker_id', 'status')
21+
22+
# capabilities
23+
allow_fetch = True
24+
allow_commit = True
25+
allow_list = True
26+
27+
gateway_id = resource.URI('gateway_id')
28+
29+
# Properties
30+
id = resource.Body("id")
31+
marker_id = resource.Body("marker_id", type=int)
32+
created_at = resource.Body("created_at")
33+
updated_at = resource.Body("updated_at")
34+
domain_id = resource.Body("domain_id")
35+
status = resource.Body("status")

otcextensions/sdk/vlb/v3/_proxy.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,21 @@ def wait_for_load_balancer(self, name_or_id, status='ACTIVE',
133133
return resource.wait_for_status(self, lb, status, failures, interval,
134134
wait, attribute='provisioning_status')
135135

136+
def wait_for_delete_load_balancer(self, name_or_id, interval=2, wait=300):
137+
"""Wait for a load balancer to be deleted.
138+
139+
:param name_or_id: The name or ID of a load balancer.
140+
:param interval: Number of seconds to wait between checks.
141+
Default is 2.
142+
:param wait: Maximum number of seconds to wait for deletion.
143+
Default is 300.
144+
:returns: True if the resource is deleted, False if timeout.
145+
:raises: :class:`~openstack.exceptions.ResourceTimeout` if transition
146+
to delete failed to occur in the specified seconds.
147+
"""
148+
lb = self._get_resource(_lb.LoadBalancer, name_or_id)
149+
return resource.wait_for_delete(self, lb, interval, wait)
150+
136151
def get_load_balancer_statuses(self, loadbalancer_id):
137152
"""Get specific load balancer statuses by load balancer id.
138153

otcextensions/sdk/vpcep/v1/_proxy.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,8 @@ def manage_service_connections(self, service, action, endpoints=[]):
210210
:param action: action can be ``accept`` or ``reject``.
211211
:param endpoints: List of VPC Endpoints Id.
212212
213-
:returns: A generator of connection objects.
214-
:rtype: :class:`~otcextensions.sdk.vpcep.connection.Connection`
213+
:returns: List of connection objects.
215214
"""
216-
217215
endpoint_service = self._get_resource(_service.Service, service)
218216
connection = self._get_resource(
219217
_connection.Connection,

otcextensions/sdk/vpcep/v1/connection.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ def _action(self, session, action, endpoints=[]):
5454
body = {'endpoints': endpoints, 'action': action}
5555
response = session.post(uri, json=body)
5656
exceptions.raise_from_response(response)
57-
for raw_resource in response.json()[self.resources_key]:
58-
yield Connection.existing(**raw_resource)
57+
return [
58+
Connection.existing(**raw_resource)
59+
for raw_resource in response.json()[self.resources_key]
60+
]
5961

6062
def accept(self, session, endpoints=[]):
6163
"""Accept connections."""

otcextensions/tests/functional/base.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# under the License.
1212

1313
import os
14+
import uuid
1415

1516
from keystoneauth1 import exceptions as _exceptions
1617

@@ -72,3 +73,86 @@ def setUp(self):
7273
except _exceptions.EndpointNotFound:
7374
self.skipTest('Service {service_type} not found in cloud'.format(
7475
service_type=service_type))
76+
77+
78+
class NetworkBaseFunctionalTest(BaseFunctionalTest):
79+
def create_network(self, prefix='sdk-test'):
80+
cidr = '192.168.0.0/16'
81+
ipv4 = 4
82+
uuid_v4 = uuid.uuid4().hex[:8]
83+
router_name = prefix + '-router-' + uuid_v4
84+
net_name = prefix + '-net-' + uuid_v4
85+
subnet_name = prefix + '-subnet-' + uuid_v4
86+
87+
network = self.conn.network.create_network(name=net_name)
88+
self.assertEqual(net_name, network.name)
89+
net_id = network.id
90+
subnet = self.conn.network.create_subnet(
91+
name=subnet_name,
92+
ip_version=ipv4,
93+
network_id=net_id,
94+
cidr=cidr
95+
)
96+
self.assertEqual(subnet_name, subnet.name)
97+
subnet_id = subnet.id
98+
99+
router = self.conn.network.create_router(name=router_name)
100+
self.assertEqual(router_name, router.name)
101+
router_id = router.id
102+
interface = router.add_interface(
103+
self.conn.network,
104+
subnet_id=subnet_id
105+
)
106+
self.assertEqual(interface['subnet_id'], subnet_id)
107+
self.assertIn('port_id', interface)
108+
return {
109+
'router_id': router_id,
110+
'subnet_id': subnet_id,
111+
'network_id': net_id
112+
}
113+
114+
def destroy_network(self, params: dict):
115+
router_id = params.get('router_id')
116+
subnet_id = params.get('subnet_id')
117+
network_id = params.get('network_id')
118+
router = self.conn.network.get_router(router_id)
119+
120+
interface = router.remove_interface(
121+
self.conn.network,
122+
subnet_id=subnet_id
123+
)
124+
self.assertEqual(interface['subnet_id'], subnet_id)
125+
self.assertIn('port_id', interface)
126+
sot = self.conn.network.delete_router(
127+
router_id,
128+
ignore_missing=False
129+
)
130+
self.assertIsNone(sot)
131+
sot = self.conn.network.delete_subnet(
132+
subnet_id,
133+
ignore_missing=False
134+
)
135+
self.assertIsNone(sot)
136+
sot = self.conn.network.delete_network(
137+
network_id,
138+
ignore_missing=False
139+
)
140+
self.assertIsNone(sot)
141+
142+
def create_port(self, network_id, prefix='sdk-test'):
143+
uuid_v4 = uuid.uuid4().hex[:8]
144+
port_name = prefix + '-port-' + uuid_v4
145+
146+
port = self.conn.network.create_port(
147+
name=port_name,
148+
network_id=network_id
149+
)
150+
self.assertEqual(port_name, port.name)
151+
return port
152+
153+
def destroy_port(self, port):
154+
sot = self.conn.network.delete_port(
155+
port,
156+
ignore_missing=False
157+
)
158+
self.assertIsNone(sot)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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 otcextensions.tests.functional.sdk.apig import TestApiG
14+
15+
16+
class TestVpcEndpoint(TestApiG):
17+
gateway = ""
18+
19+
def setUp(self):
20+
super(TestVpcEndpoint, self).setUp()
21+
22+
def test_01_list_vpc_endpoint(self):
23+
self.conn.vpcep.create_endpoint(
24+
subnet_id='',
25+
endpoint_service_id='',
26+
vpc_id='',
27+
)
28+
list(self.client.vpc_endpoints(
29+
gateway=TestVpcEndpoint.gateway,
30+
))

0 commit comments

Comments
 (0)