Skip to content

Commit

Permalink
fixes(api) allow no v2 api
Browse files Browse the repository at this point in the history
Allow client without no V2 api

Closes #220
  • Loading branch information
antechrestos committed Jan 4, 2025
1 parent 67bf195 commit 0fc3f7a
Show file tree
Hide file tree
Showing 37 changed files with 139 additions and 81 deletions.
62 changes: 46 additions & 16 deletions cloudfoundry_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,28 @@
class Info:
def __init__(
self,
api_v2_version: str,
api_v2_url: str,
api_v3_url: str,
authorization_endpoint: str,
api_endpoint: str,
doppler_endpoint: Optional[str],
log_stream_endpoint: Optional[str],
):
self.api_v2_version = api_v2_version
self._api_v2_url = api_v2_url
self._api_v3_url = api_v3_url
self.authorization_endpoint = authorization_endpoint
self.api_endpoint = api_endpoint
self.doppler_endpoint = doppler_endpoint
self.log_stream_endpoint = log_stream_endpoint

@property
def api_v2_url(self) -> Optional[str]:
return self._api_v2_url

@property
def api_v3_url(self) -> Optional[str]:
return self._api_v3_url


class NetworkingV1External(object):
def __init__(self, target_endpoint: str, credential_manager: "CloudFoundryClient"):
Expand All @@ -83,18 +93,18 @@ def __init__(self, target_endpoint: str, credential_manager: "CloudFoundryClient
self.service_plans = ServicePlanManagerV2(target_endpoint, credential_manager)
# Default implementations
self.event = EventManager(target_endpoint, credential_manager)
self.organizations = EntityManagerV2(target_endpoint, credential_manager, "/v2/organizations")
self.private_domains = EntityManagerV2(target_endpoint, credential_manager, "/v2/private_domains")
self.organizations = EntityManagerV2(target_endpoint, credential_manager, "/organizations")
self.private_domains = EntityManagerV2(target_endpoint, credential_manager, "/private_domains")
self.routes = RouteManager(target_endpoint, credential_manager)
self.services = EntityManagerV2(target_endpoint, credential_manager, "/v2/services")
self.shared_domains = EntityManagerV2(target_endpoint, credential_manager, "/v2/shared_domains")
self.services = EntityManagerV2(target_endpoint, credential_manager, "/services")
self.shared_domains = EntityManagerV2(target_endpoint, credential_manager, "/shared_domains")
self.spaces = SpaceManagerV2(target_endpoint, credential_manager)
self.stacks = EntityManagerV2(target_endpoint, credential_manager, "/v2/stacks")
self.stacks = EntityManagerV2(target_endpoint, credential_manager, "/stacks")
self.user_provided_service_instances = EntityManagerV2(
target_endpoint, credential_manager, "/v2/user_provided_service_instances"
target_endpoint, credential_manager, "/user_provided_service_instances"
)
self.security_groups = EntityManagerV2(target_endpoint, credential_manager, "/v2/security_groups")
self.users = EntityManagerV2(target_endpoint, credential_manager, "/v2/users")
self.security_groups = EntityManagerV2(target_endpoint, credential_manager, "/security_groups")
self.users = EntityManagerV2(target_endpoint, credential_manager, "/users")
# Resources implementation used by push operation
self.resources = ResourceManager(target_endpoint, credential_manager)

Expand Down Expand Up @@ -146,8 +156,6 @@ def __init__(self, target_endpoint: str, client_id: str = "cf", client_secret: s
self.login_hint = kwargs.get("login_hint")
target_endpoint_trimmed = target_endpoint.rstrip("/")
info = self._get_info(target_endpoint_trimmed, proxy, verify=verify)
if not info.api_v2_version.startswith("2."):
raise AssertionError("Only version 2 is supported for now. Found %s" % info.api_v2_version)
service_information = ServiceInformation(
None, "%s/oauth/token" % info.authorization_endpoint, client_id, client_secret, [], verify
)
Expand All @@ -156,8 +164,16 @@ def __init__(self, target_endpoint: str, client_id: str = "cf", client_secret: s
proxies=proxy,
user_agent=kwargs.get("user_agent", "cf-python-client")
)
self.v2 = V2(target_endpoint_trimmed, self)
self.v3 = V3(target_endpoint_trimmed, self)
self._v2 = (
V2(info.api_v2_url, self)
if info.api_v2_url is not None
else None
)
self._v3 = (
V3(info.api_v3_url, self)
if info.api_v3_url is not None
else None
)
self._doppler = (
DopplerClient(
info.doppler_endpoint,
Expand All @@ -181,6 +197,18 @@ def __init__(self, target_endpoint: str, client_id: str = "cf", client_secret: s
self.networking_v1_external = NetworkingV1External(target_endpoint_trimmed, self)
self.info = info

@property
def v2(self) -> V2:
if self._v2 is None:
raise NotImplementedError("No V2 endpoint for this instance")
return self._v2

@property
def v3(self) -> V3:
if self._v3 is None:
raise NotImplementedError("No V3 endpoint for this instance")
return self._v3

@property
def doppler(self) -> DopplerClient:
if self._doppler is None:
Expand All @@ -194,7 +222,6 @@ def rlpgateway(self):
if self._rlpgateway is None:
raise NotImplementedError("No RLP gateway endpoint for this instance")
else:

return self._rlpgateway

def _get_info(self, target_endpoint: str, proxy: Optional[dict] = None, verify: bool = True) -> Info:
Expand All @@ -206,8 +233,11 @@ def _get_info(self, target_endpoint: str, proxy: Optional[dict] = None, verify:
root_links = root_info["links"]
logging = root_links.get("logging")
log_stream = root_links.get("log_stream")
cloud_controller_v2 = root_links.get("cloud_controller_v2")
cloud_controller_v3 = root_links.get("cloud_controller_v3")
return Info(
root_links["cloud_controller_v2"]["meta"]["version"],
cloud_controller_v2["href"] if cloud_controller_v2 is not None else None,
cloud_controller_v3["href"] if cloud_controller_v3 is not None else None,
self._resolve_login_endpoint(root_links),
target_endpoint,
logging.get("href") if logging is not None else None,
Expand Down
4 changes: 2 additions & 2 deletions cloudfoundry_client/common_objects.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import json
from typing import Callable, TypeVar, Generic, List, Union
from typing import Callable, TypeVar, Generic, List, Optional


class Request(dict):
Expand All @@ -21,7 +21,7 @@ def __init__(self, *args, **kwargs):
class Pagination(Generic[ENTITY]):
def __init__(self, first_page: JsonObject,
total_result: int,
next_page_loader: Callable[[JsonObject], Union[None, JsonObject]],
next_page_loader: Callable[[JsonObject], Optional[JsonObject]],
resources_accessor: Callable[[JsonObject], List[JsonObject]],
instance_creator: Callable[[JsonObject], ENTITY]):
self._first_page = first_page
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v2/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class AppManager(EntityManager):

def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(AppManager, self).__init__(
target_endpoint, client, "/v2/apps", lambda pairs: Application(target_endpoint, client, pairs)
target_endpoint, client, "/apps", lambda pairs: Application(target_endpoint, client, pairs)
)

def get_stats(self, application_guid: str) -> Dict[str, JsonObject]:
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v2/buildpacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class BuildpackManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(BuildpackManager, self).__init__(target_endpoint, client, "/v2/buildpacks")
super(BuildpackManager, self).__init__(target_endpoint, client, "/buildpacks")

def update(self, buildpack_guid: str, parameters: dict) -> Entity:
return super(BuildpackManager, self)._update(buildpack_guid, parameters)
4 changes: 2 additions & 2 deletions cloudfoundry_client/v2/entities.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from functools import partial, reduce
from typing import Callable, List, Tuple, Any, Optional, TYPE_CHECKING, Union
from typing import Callable, List, Tuple, Any, Optional, TYPE_CHECKING
from urllib.parse import quote
from requests import Response

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

def _next_page(self, current_page: JsonObject) -> Union[None, JsonObject]:
def _next_page(self, current_page: JsonObject) -> Optional[JsonObject]:
next_url = current_page.get("next_url")
if next_url is None:
return None
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v2/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class EventManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(EventManager, self).__init__(target_endpoint, client, "/v2/events")
super(EventManager, self).__init__(target_endpoint, client, "/events")

def list_by_type(self, event_type: str) -> Generator[Entity, None, None]:
return self._list(self.entity_uri, type=event_type)
2 changes: 1 addition & 1 deletion cloudfoundry_client/v2/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
self.client = client

def get(self, job_guid: str) -> JsonObject:
return self.client.get("%s/v2/jobs/%s" % (self.target_endpoint, job_guid)).json(object_pairs_hook=JsonObject)
return self.client.get("%s/jobs/%s" % (self.target_endpoint, job_guid)).json(object_pairs_hook=JsonObject)
2 changes: 1 addition & 1 deletion cloudfoundry_client/v2/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
self.client = client

def match(self, items: List[dict]) -> List[JsonObject]:
response = self.client.put("%s/v2/resource_match" % self.client.info.api_endpoint, json=items)
response = self.client.put("%s/resource_match" % self.client.info.api_endpoint, json=items)
return response.json(object_pairs_hook=JsonObject)
2 changes: 1 addition & 1 deletion cloudfoundry_client/v2/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class RouteManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(RouteManager, self).__init__(target_endpoint, client, "/v2/routes")
super(RouteManager, self).__init__(target_endpoint, client, "/routes")

def create_tcp_route(self, domain_guid: str, space_guid: str, port: Optional[int] = None) -> Entity:
request = self._request(domain_guid=domain_guid, space_guid=space_guid)
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v2/service_bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class ServiceBindingManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(ServiceBindingManager, self).__init__(target_endpoint, client, "/v2/service_bindings")
super(ServiceBindingManager, self).__init__(target_endpoint, client, "/service_bindings")

def create(self, app_guid: str, instance_guid: str, parameters: Optional[dict] = None, name: Optional[str] = None) -> Entity:
request = self._request(app_guid=app_guid, service_instance_guid=instance_guid)
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v2/service_brokers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class ServiceBrokerManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(ServiceBrokerManager, self).__init__(target_endpoint, client, "/v2/service_brokers")
super(ServiceBrokerManager, self).__init__(target_endpoint, client, "/service_brokers")

def create(
self, broker_url: str, broker_name: str, auth_username: str, auth_password: str, space_guid: Optional[str] = None
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v2/service_instances.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class ServiceInstanceManager(EntityManager):
list_query_parameters = ["page", "results-per-page", "order-direction", "return_user_provided_service_instances"]

def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(ServiceInstanceManager, self).__init__(target_endpoint, client, "/v2/service_instances")
super(ServiceInstanceManager, self).__init__(target_endpoint, client, "/service_instances")

def create(
self,
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v2/service_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class ServiceKeyManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(ServiceKeyManager, self).__init__(target_endpoint, client, "/v2/service_keys")
super(ServiceKeyManager, self).__init__(target_endpoint, client, "/service_keys")

def create(self, service_instance_guid: str, name: str, parameters: Optional[dict] = None) -> Entity:
request = self._request(service_instance_guid=service_instance_guid, name=name)
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v2/service_plan_visibilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class ServicePlanVisibilityManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(ServicePlanVisibilityManager, self).__init__(target_endpoint, client, "/v2/service_plan_visibilities")
super(ServicePlanVisibilityManager, self).__init__(target_endpoint, client, "/service_plan_visibilities")

def create(self, service_plan_guid: str, organization_guid: str) -> Entity:
request = self._request()
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v2/service_plans.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class ServicePlanManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(ServicePlanManager, self).__init__(target_endpoint, client, "/v2/service_plans")
super(ServicePlanManager, self).__init__(target_endpoint, client, "/service_plans")

def create_from_resource_file(self, path: str) -> Entity:
raise NotImplementedError("No creation allowed")
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v2/spaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class SpaceManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(SpaceManager, self).__init__(target_endpoint, client, "/v2/spaces")
super(SpaceManager, self).__init__(target_endpoint, client, "/spaces")

def delete_unmapped_routes(self, space_guid: str):
url = "%s%s/%s/unmapped_routes" % (self.target_endpoint, self.entity_uri, space_guid)
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v3/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class AppManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(AppManager, self).__init__(target_endpoint, client, "/v3/apps")
super(AppManager, self).__init__(target_endpoint, client, "/apps")

def restart(self, application_guid: str):
return super(AppManager, self)._post("%s%s/%s/actions/restart" % (self.target_endpoint,
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v3/buildpacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class BuildpackManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(BuildpackManager, self).__init__(target_endpoint, client, "/v3/buildpacks")
super(BuildpackManager, self).__init__(target_endpoint, client, "/buildpacks")

def create(
self,
Expand Down
4 changes: 2 additions & 2 deletions cloudfoundry_client/v3/domains.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def __init__(self, target_endpoint: str, client: "CloudFoundryClient", **kwargs)

class DomainManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(DomainManager, self).__init__(target_endpoint, client, "/v3/domains", Domain)
super(DomainManager, self).__init__(target_endpoint, client, "/domains", Domain)

def create(
self,
Expand All @@ -44,7 +44,7 @@ def create(
return super(DomainManager, self)._create(data)

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

def update(self, domain_guid: str, meta_labels: Optional[dict] = None, meta_annotations: Optional[dict] = None) -> Domain:
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v3/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ def _entity(json_object: JsonObject) -> Entity:
lambda p: p["resources"],
_entity)

def _next_page(self, current_page: JsonObject) -> Union[None, JsonObject]:
def _next_page(self, current_page: JsonObject) -> Optional[JsonObject]:
pagination = current_page.get("pagination")
if (
pagination is None
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v3/feature_flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class FeatureFlagManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(FeatureFlagManager, self).__init__(target_endpoint, client, "/v3/feature_flags")
super(FeatureFlagManager, self).__init__(target_endpoint, client, "/feature_flags")

def update(self, name: str, enabled: Optional[bool] = True, custom_error_message: Optional[str] = None) -> Entity:
data = {"enabled": enabled, "custom_error_message": custom_error_message}
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v3/isolation_segments.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class IsolationSegmentManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(IsolationSegmentManager, self).__init__(target_endpoint, client, "/v3/isolation_segments")
super(IsolationSegmentManager, self).__init__(target_endpoint, client, "/isolation_segments")

def create(self, name: str, meta_labels: Optional[dict] = None, meta_annotations: Optional[dict] = None) -> Entity:
data = {"name": name, "metadata": {"labels": meta_labels, "annotations": meta_annotations}}
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v3/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class JobTimeout(Exception):

class JobManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(JobManager, self).__init__(target_endpoint, client, "/v3/jobs")
super(JobManager, self).__init__(target_endpoint, client, "/jobs")

def wait_for_job_completion(
self,
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v3/organization_quotas.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class DomainsQuota:

class OrganizationQuotaManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super().__init__(target_endpoint, client, "/v3/organization_quotas")
super().__init__(target_endpoint, client, "/organization_quotas")

def remove(self, guid: str, asynchronous: bool = True) -> Optional[str]:
return super()._remove(guid, asynchronous)
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v3/organizations.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class OrganizationManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(OrganizationManager, self).__init__(target_endpoint, client, "/v3/organizations")
super(OrganizationManager, self).__init__(target_endpoint, client, "/organizations")

def create(
self, name: str, suspended: bool, meta_labels: Optional[dict] = None, meta_annotations: Optional[dict] = None
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v3/processes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@

class ProcessManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(ProcessManager, self).__init__(target_endpoint, client, "/v3/processes")
super(ProcessManager, self).__init__(target_endpoint, client, "/processes")
2 changes: 1 addition & 1 deletion cloudfoundry_client/v3/roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class RoleManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(RoleManager, self).__init__(target_endpoint, client, "/v3/roles")
super(RoleManager, self).__init__(target_endpoint, client, "/roles")

def remove(self, role_guid: str, asynchronous: bool = True) -> Optional[str]:
return super(RoleManager, self)._remove(role_guid, asynchronous)
2 changes: 1 addition & 1 deletion cloudfoundry_client/v3/security_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class GloballyEnabled:

class SecurityGroupManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(SecurityGroupManager, self).__init__(target_endpoint, client, "/v3/security_groups")
super(SecurityGroupManager, self).__init__(target_endpoint, client, "/security_groups")

def create(self,
name: str,
Expand Down
2 changes: 1 addition & 1 deletion cloudfoundry_client/v3/service_brokers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class ServiceBrokerManager(EntityManager):
def __init__(self, target_endpoint: str, client: "CloudFoundryClient"):
super(ServiceBrokerManager, self).__init__(target_endpoint, client, "/v3/service_brokers")
super(ServiceBrokerManager, self).__init__(target_endpoint, client, "/service_brokers")

def create(
self,
Expand Down
Loading

0 comments on commit 0fc3f7a

Please sign in to comment.