Skip to content

Commit 0fc3f7a

Browse files
committed
fixes(api) allow no v2 api
Allow client without no V2 api Closes #220
1 parent 67bf195 commit 0fc3f7a

37 files changed

+139
-81
lines changed

cloudfoundry_client/client.py

+46-16
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,28 @@
5252
class Info:
5353
def __init__(
5454
self,
55-
api_v2_version: str,
55+
api_v2_url: str,
56+
api_v3_url: str,
5657
authorization_endpoint: str,
5758
api_endpoint: str,
5859
doppler_endpoint: Optional[str],
5960
log_stream_endpoint: Optional[str],
6061
):
61-
self.api_v2_version = api_v2_version
62+
self._api_v2_url = api_v2_url
63+
self._api_v3_url = api_v3_url
6264
self.authorization_endpoint = authorization_endpoint
6365
self.api_endpoint = api_endpoint
6466
self.doppler_endpoint = doppler_endpoint
6567
self.log_stream_endpoint = log_stream_endpoint
6668

69+
@property
70+
def api_v2_url(self) -> Optional[str]:
71+
return self._api_v2_url
72+
73+
@property
74+
def api_v3_url(self) -> Optional[str]:
75+
return self._api_v3_url
76+
6777

6878
class NetworkingV1External(object):
6979
def __init__(self, target_endpoint: str, credential_manager: "CloudFoundryClient"):
@@ -83,18 +93,18 @@ def __init__(self, target_endpoint: str, credential_manager: "CloudFoundryClient
8393
self.service_plans = ServicePlanManagerV2(target_endpoint, credential_manager)
8494
# Default implementations
8595
self.event = EventManager(target_endpoint, credential_manager)
86-
self.organizations = EntityManagerV2(target_endpoint, credential_manager, "/v2/organizations")
87-
self.private_domains = EntityManagerV2(target_endpoint, credential_manager, "/v2/private_domains")
96+
self.organizations = EntityManagerV2(target_endpoint, credential_manager, "/organizations")
97+
self.private_domains = EntityManagerV2(target_endpoint, credential_manager, "/private_domains")
8898
self.routes = RouteManager(target_endpoint, credential_manager)
89-
self.services = EntityManagerV2(target_endpoint, credential_manager, "/v2/services")
90-
self.shared_domains = EntityManagerV2(target_endpoint, credential_manager, "/v2/shared_domains")
99+
self.services = EntityManagerV2(target_endpoint, credential_manager, "/services")
100+
self.shared_domains = EntityManagerV2(target_endpoint, credential_manager, "/shared_domains")
91101
self.spaces = SpaceManagerV2(target_endpoint, credential_manager)
92-
self.stacks = EntityManagerV2(target_endpoint, credential_manager, "/v2/stacks")
102+
self.stacks = EntityManagerV2(target_endpoint, credential_manager, "/stacks")
93103
self.user_provided_service_instances = EntityManagerV2(
94-
target_endpoint, credential_manager, "/v2/user_provided_service_instances"
104+
target_endpoint, credential_manager, "/user_provided_service_instances"
95105
)
96-
self.security_groups = EntityManagerV2(target_endpoint, credential_manager, "/v2/security_groups")
97-
self.users = EntityManagerV2(target_endpoint, credential_manager, "/v2/users")
106+
self.security_groups = EntityManagerV2(target_endpoint, credential_manager, "/security_groups")
107+
self.users = EntityManagerV2(target_endpoint, credential_manager, "/users")
98108
# Resources implementation used by push operation
99109
self.resources = ResourceManager(target_endpoint, credential_manager)
100110

@@ -146,8 +156,6 @@ def __init__(self, target_endpoint: str, client_id: str = "cf", client_secret: s
146156
self.login_hint = kwargs.get("login_hint")
147157
target_endpoint_trimmed = target_endpoint.rstrip("/")
148158
info = self._get_info(target_endpoint_trimmed, proxy, verify=verify)
149-
if not info.api_v2_version.startswith("2."):
150-
raise AssertionError("Only version 2 is supported for now. Found %s" % info.api_v2_version)
151159
service_information = ServiceInformation(
152160
None, "%s/oauth/token" % info.authorization_endpoint, client_id, client_secret, [], verify
153161
)
@@ -156,8 +164,16 @@ def __init__(self, target_endpoint: str, client_id: str = "cf", client_secret: s
156164
proxies=proxy,
157165
user_agent=kwargs.get("user_agent", "cf-python-client")
158166
)
159-
self.v2 = V2(target_endpoint_trimmed, self)
160-
self.v3 = V3(target_endpoint_trimmed, self)
167+
self._v2 = (
168+
V2(info.api_v2_url, self)
169+
if info.api_v2_url is not None
170+
else None
171+
)
172+
self._v3 = (
173+
V3(info.api_v3_url, self)
174+
if info.api_v3_url is not None
175+
else None
176+
)
161177
self._doppler = (
162178
DopplerClient(
163179
info.doppler_endpoint,
@@ -181,6 +197,18 @@ def __init__(self, target_endpoint: str, client_id: str = "cf", client_secret: s
181197
self.networking_v1_external = NetworkingV1External(target_endpoint_trimmed, self)
182198
self.info = info
183199

200+
@property
201+
def v2(self) -> V2:
202+
if self._v2 is None:
203+
raise NotImplementedError("No V2 endpoint for this instance")
204+
return self._v2
205+
206+
@property
207+
def v3(self) -> V3:
208+
if self._v3 is None:
209+
raise NotImplementedError("No V3 endpoint for this instance")
210+
return self._v3
211+
184212
@property
185213
def doppler(self) -> DopplerClient:
186214
if self._doppler is None:
@@ -194,7 +222,6 @@ def rlpgateway(self):
194222
if self._rlpgateway is None:
195223
raise NotImplementedError("No RLP gateway endpoint for this instance")
196224
else:
197-
198225
return self._rlpgateway
199226

200227
def _get_info(self, target_endpoint: str, proxy: Optional[dict] = None, verify: bool = True) -> Info:
@@ -206,8 +233,11 @@ def _get_info(self, target_endpoint: str, proxy: Optional[dict] = None, verify:
206233
root_links = root_info["links"]
207234
logging = root_links.get("logging")
208235
log_stream = root_links.get("log_stream")
236+
cloud_controller_v2 = root_links.get("cloud_controller_v2")
237+
cloud_controller_v3 = root_links.get("cloud_controller_v3")
209238
return Info(
210-
root_links["cloud_controller_v2"]["meta"]["version"],
239+
cloud_controller_v2["href"] if cloud_controller_v2 is not None else None,
240+
cloud_controller_v3["href"] if cloud_controller_v3 is not None else None,
211241
self._resolve_login_endpoint(root_links),
212242
target_endpoint,
213243
logging.get("href") if logging is not None else None,

cloudfoundry_client/common_objects.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import json
2-
from typing import Callable, TypeVar, Generic, List, Union
2+
from typing import Callable, TypeVar, Generic, List, Optional
33

44

55
class Request(dict):
@@ -21,7 +21,7 @@ def __init__(self, *args, **kwargs):
2121
class Pagination(Generic[ENTITY]):
2222
def __init__(self, first_page: JsonObject,
2323
total_result: int,
24-
next_page_loader: Callable[[JsonObject], Union[None, JsonObject]],
24+
next_page_loader: Callable[[JsonObject], Optional[JsonObject]],
2525
resources_accessor: Callable[[JsonObject], List[JsonObject]],
2626
instance_creator: Callable[[JsonObject], ENTITY]):
2727
self._first_page = first_page

cloudfoundry_client/v2/apps.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class AppManager(EntityManager):
7777

7878
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
7979
super(AppManager, self).__init__(
80-
target_endpoint, client, "/v2/apps", lambda pairs: Application(target_endpoint, client, pairs)
80+
target_endpoint, client, "/apps", lambda pairs: Application(target_endpoint, client, pairs)
8181
)
8282

8383
def get_stats(self, application_guid: str) -> Dict[str, JsonObject]:

cloudfoundry_client/v2/buildpacks.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class BuildpackManager(EntityManager):
1010
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
11-
super(BuildpackManager, self).__init__(target_endpoint, client, "/v2/buildpacks")
11+
super(BuildpackManager, self).__init__(target_endpoint, client, "/buildpacks")
1212

1313
def update(self, buildpack_guid: str, parameters: dict) -> Entity:
1414
return super(BuildpackManager, self)._update(buildpack_guid, parameters)

cloudfoundry_client/v2/entities.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from functools import partial, reduce
2-
from typing import Callable, List, Tuple, Any, Optional, TYPE_CHECKING, Union
2+
from typing import Callable, List, Tuple, Any, Optional, TYPE_CHECKING
33
from urllib.parse import quote
44
from requests import Response
55

@@ -68,7 +68,7 @@ def _list(self, requested_path: str, entity_builder: Optional[EntityBuilder] = N
6868
lambda page: page["resources"],
6969
lambda json_object: current_builder(list(json_object.items())))
7070

71-
def _next_page(self, current_page: JsonObject) -> Union[None, JsonObject]:
71+
def _next_page(self, current_page: JsonObject) -> Optional[JsonObject]:
7272
next_url = current_page.get("next_url")
7373
if next_url is None:
7474
return None

cloudfoundry_client/v2/events.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class EventManager(EntityManager):
1010
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
11-
super(EventManager, self).__init__(target_endpoint, client, "/v2/events")
11+
super(EventManager, self).__init__(target_endpoint, client, "/events")
1212

1313
def list_by_type(self, event_type: str) -> Generator[Entity, None, None]:
1414
return self._list(self.entity_uri, type=event_type)

cloudfoundry_client/v2/jobs.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
1212
self.client = client
1313

1414
def get(self, job_guid: str) -> JsonObject:
15-
return self.client.get("%s/v2/jobs/%s" % (self.target_endpoint, job_guid)).json(object_pairs_hook=JsonObject)
15+
return self.client.get("%s/jobs/%s" % (self.target_endpoint, job_guid)).json(object_pairs_hook=JsonObject)

cloudfoundry_client/v2/resources.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
1212
self.client = client
1313

1414
def match(self, items: List[dict]) -> List[JsonObject]:
15-
response = self.client.put("%s/v2/resource_match" % self.client.info.api_endpoint, json=items)
15+
response = self.client.put("%s/resource_match" % self.client.info.api_endpoint, json=items)
1616
return response.json(object_pairs_hook=JsonObject)

cloudfoundry_client/v2/routes.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class RouteManager(EntityManager):
1010
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
11-
super(RouteManager, self).__init__(target_endpoint, client, "/v2/routes")
11+
super(RouteManager, self).__init__(target_endpoint, client, "/routes")
1212

1313
def create_tcp_route(self, domain_guid: str, space_guid: str, port: Optional[int] = None) -> Entity:
1414
request = self._request(domain_guid=domain_guid, space_guid=space_guid)

cloudfoundry_client/v2/service_bindings.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class ServiceBindingManager(EntityManager):
1010
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
11-
super(ServiceBindingManager, self).__init__(target_endpoint, client, "/v2/service_bindings")
11+
super(ServiceBindingManager, self).__init__(target_endpoint, client, "/service_bindings")
1212

1313
def create(self, app_guid: str, instance_guid: str, parameters: Optional[dict] = None, name: Optional[str] = None) -> Entity:
1414
request = self._request(app_guid=app_guid, service_instance_guid=instance_guid)

cloudfoundry_client/v2/service_brokers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class ServiceBrokerManager(EntityManager):
1010
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
11-
super(ServiceBrokerManager, self).__init__(target_endpoint, client, "/v2/service_brokers")
11+
super(ServiceBrokerManager, self).__init__(target_endpoint, client, "/service_brokers")
1212

1313
def create(
1414
self, broker_url: str, broker_name: str, auth_username: str, auth_password: str, space_guid: Optional[str] = None

cloudfoundry_client/v2/service_instances.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class ServiceInstanceManager(EntityManager):
1010
list_query_parameters = ["page", "results-per-page", "order-direction", "return_user_provided_service_instances"]
1111

1212
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
13-
super(ServiceInstanceManager, self).__init__(target_endpoint, client, "/v2/service_instances")
13+
super(ServiceInstanceManager, self).__init__(target_endpoint, client, "/service_instances")
1414

1515
def create(
1616
self,

cloudfoundry_client/v2/service_keys.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class ServiceKeyManager(EntityManager):
1010
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
11-
super(ServiceKeyManager, self).__init__(target_endpoint, client, "/v2/service_keys")
11+
super(ServiceKeyManager, self).__init__(target_endpoint, client, "/service_keys")
1212

1313
def create(self, service_instance_guid: str, name: str, parameters: Optional[dict] = None) -> Entity:
1414
request = self._request(service_instance_guid=service_instance_guid, name=name)

cloudfoundry_client/v2/service_plan_visibilities.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class ServicePlanVisibilityManager(EntityManager):
1010
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
11-
super(ServicePlanVisibilityManager, self).__init__(target_endpoint, client, "/v2/service_plan_visibilities")
11+
super(ServicePlanVisibilityManager, self).__init__(target_endpoint, client, "/service_plan_visibilities")
1212

1313
def create(self, service_plan_guid: str, organization_guid: str) -> Entity:
1414
request = self._request()

cloudfoundry_client/v2/service_plans.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
class ServicePlanManager(EntityManager):
1111
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
12-
super(ServicePlanManager, self).__init__(target_endpoint, client, "/v2/service_plans")
12+
super(ServicePlanManager, self).__init__(target_endpoint, client, "/service_plans")
1313

1414
def create_from_resource_file(self, path: str) -> Entity:
1515
raise NotImplementedError("No creation allowed")

cloudfoundry_client/v2/spaces.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class SpaceManager(EntityManager):
1010
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
11-
super(SpaceManager, self).__init__(target_endpoint, client, "/v2/spaces")
11+
super(SpaceManager, self).__init__(target_endpoint, client, "/spaces")
1212

1313
def delete_unmapped_routes(self, space_guid: str):
1414
url = "%s%s/%s/unmapped_routes" % (self.target_endpoint, self.entity_uri, space_guid)

cloudfoundry_client/v3/apps.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
class AppManager(EntityManager):
1111
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
12-
super(AppManager, self).__init__(target_endpoint, client, "/v3/apps")
12+
super(AppManager, self).__init__(target_endpoint, client, "/apps")
1313

1414
def restart(self, application_guid: str):
1515
return super(AppManager, self)._post("%s%s/%s/actions/restart" % (self.target_endpoint,

cloudfoundry_client/v3/buildpacks.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class BuildpackManager(EntityManager):
1010
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
11-
super(BuildpackManager, self).__init__(target_endpoint, client, "/v3/buildpacks")
11+
super(BuildpackManager, self).__init__(target_endpoint, client, "/buildpacks")
1212

1313
def create(
1414
self,

cloudfoundry_client/v3/domains.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def __init__(self, target_endpoint: str, client: "CloudFoundryClient", **kwargs)
2121

2222
class DomainManager(EntityManager):
2323
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
24-
super(DomainManager, self).__init__(target_endpoint, client, "/v3/domains", Domain)
24+
super(DomainManager, self).__init__(target_endpoint, client, "/domains", Domain)
2525

2626
def create(
2727
self,
@@ -44,7 +44,7 @@ def create(
4444
return super(DomainManager, self)._create(data)
4545

4646
def list_domains_for_org(self, org_guid: str, **kwargs) -> Pagination[Entity]:
47-
uri = "/v3/organizations/{guid}/domains".format(guid=org_guid)
47+
uri = "/organizations/{guid}/domains".format(guid=org_guid)
4848
return self._list(uri, **kwargs)
4949

5050
def update(self, domain_guid: str, meta_labels: Optional[dict] = None, meta_annotations: Optional[dict] = None) -> Domain:

cloudfoundry_client/v3/entities.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ def _entity(json_object: JsonObject) -> Entity:
188188
lambda p: p["resources"],
189189
_entity)
190190

191-
def _next_page(self, current_page: JsonObject) -> Union[None, JsonObject]:
191+
def _next_page(self, current_page: JsonObject) -> Optional[JsonObject]:
192192
pagination = current_page.get("pagination")
193193
if (
194194
pagination is None

cloudfoundry_client/v3/feature_flags.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class FeatureFlagManager(EntityManager):
1010
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
11-
super(FeatureFlagManager, self).__init__(target_endpoint, client, "/v3/feature_flags")
11+
super(FeatureFlagManager, self).__init__(target_endpoint, client, "/feature_flags")
1212

1313
def update(self, name: str, enabled: Optional[bool] = True, custom_error_message: Optional[str] = None) -> Entity:
1414
data = {"enabled": enabled, "custom_error_message": custom_error_message}

cloudfoundry_client/v3/isolation_segments.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class IsolationSegmentManager(EntityManager):
1010
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
11-
super(IsolationSegmentManager, self).__init__(target_endpoint, client, "/v3/isolation_segments")
11+
super(IsolationSegmentManager, self).__init__(target_endpoint, client, "/isolation_segments")
1212

1313
def create(self, name: str, meta_labels: Optional[dict] = None, meta_annotations: Optional[dict] = None) -> Entity:
1414
data = {"name": name, "metadata": {"labels": meta_labels, "annotations": meta_annotations}}

cloudfoundry_client/v3/jobs.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class JobTimeout(Exception):
1515

1616
class JobManager(EntityManager):
1717
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
18-
super(JobManager, self).__init__(target_endpoint, client, "/v3/jobs")
18+
super(JobManager, self).__init__(target_endpoint, client, "/jobs")
1919

2020
def wait_for_job_completion(
2121
self,

cloudfoundry_client/v3/organization_quotas.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class DomainsQuota:
3535

3636
class OrganizationQuotaManager(EntityManager):
3737
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
38-
super().__init__(target_endpoint, client, "/v3/organization_quotas")
38+
super().__init__(target_endpoint, client, "/organization_quotas")
3939

4040
def remove(self, guid: str, asynchronous: bool = True) -> Optional[str]:
4141
return super()._remove(guid, asynchronous)

cloudfoundry_client/v3/organizations.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class OrganizationManager(EntityManager):
1010
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
11-
super(OrganizationManager, self).__init__(target_endpoint, client, "/v3/organizations")
11+
super(OrganizationManager, self).__init__(target_endpoint, client, "/organizations")
1212

1313
def create(
1414
self, name: str, suspended: bool, meta_labels: Optional[dict] = None, meta_annotations: Optional[dict] = None

cloudfoundry_client/v3/processes.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@
88

99
class ProcessManager(EntityManager):
1010
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
11-
super(ProcessManager, self).__init__(target_endpoint, client, "/v3/processes")
11+
super(ProcessManager, self).__init__(target_endpoint, client, "/processes")

cloudfoundry_client/v3/roles.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class RoleManager(EntityManager):
1010
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
11-
super(RoleManager, self).__init__(target_endpoint, client, "/v3/roles")
11+
super(RoleManager, self).__init__(target_endpoint, client, "/roles")
1212

1313
def remove(self, role_guid: str, asynchronous: bool = True) -> Optional[str]:
1414
return super(RoleManager, self)._remove(role_guid, asynchronous)

cloudfoundry_client/v3/security_groups.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class GloballyEnabled:
3737

3838
class SecurityGroupManager(EntityManager):
3939
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
40-
super(SecurityGroupManager, self).__init__(target_endpoint, client, "/v3/security_groups")
40+
super(SecurityGroupManager, self).__init__(target_endpoint, client, "/security_groups")
4141

4242
def create(self,
4343
name: str,

cloudfoundry_client/v3/service_brokers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class ServiceBrokerManager(EntityManager):
1010
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
11-
super(ServiceBrokerManager, self).__init__(target_endpoint, client, "/v3/service_brokers")
11+
super(ServiceBrokerManager, self).__init__(target_endpoint, client, "/service_brokers")
1212

1313
def create(
1414
self,

0 commit comments

Comments
 (0)