Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#603] Add host scheme validation #640

Merged
merged 3 commits into from
May 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions examples/workflows/upstream/coinflip.upstream.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ metadata:
generateName: coinflip-
annotations:
workflows.argoproj.io/description: |
This is an example of coin flip defined as a sequence of conditional steps.
You can also run it in Python: https://couler-proj.github.io/couler/examples/#coin-flip
This is an example of coin flip defined as a sequence of conditional steps.\
spec:
entrypoint: coinflip
templates:
Expand Down
4 changes: 4 additions & 0 deletions scripts/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ def __str__(self) -> str:

return f"""
{signature}
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.{self.method}(
url={req_url},
params={params},
Expand Down Expand Up @@ -406,6 +407,9 @@ def get_service_def() -> str:
from hera.shared import global_config
from typing import Optional, cast

def valid_host_scheme(host: str) -> bool:
return host.startswith("http://") or host.startswith("https://")

class {models_type}Service:
def __init__(
self,
Expand Down
28 changes: 28 additions & 0 deletions src/hera/events/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
from hera.shared import global_config


def valid_host_scheme(host: str) -> bool:
return host.startswith("http://") or host.startswith("https://")


class EventsService:
def __init__(
self,
Expand All @@ -54,6 +58,7 @@ def list_event_sources(
limit: Optional[str] = None,
continue_: Optional[str] = None,
) -> EventSourceList:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(self.host, "api/v1/event-sources/{namespace}").format(
namespace=namespace if namespace is not None else self.namespace
Expand All @@ -80,6 +85,7 @@ def list_event_sources(
raise Exception(f"Server returned status code {resp.status_code} with error: {resp.json()}")

def create_event_source(self, req: CreateEventSourceRequest, namespace: Optional[str] = None) -> EventSource:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.post(
url=urljoin(self.host, "api/v1/event-sources/{namespace}").format(
namespace=namespace if namespace is not None else self.namespace
Expand All @@ -98,6 +104,7 @@ def create_event_source(self, req: CreateEventSourceRequest, namespace: Optional
raise Exception(f"Server returned status code {resp.status_code} with error: {resp.json()}")

def get_event_source(self, name: str, namespace: Optional[str] = None) -> EventSource:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(self.host, "api/v1/event-sources/{namespace}/{name}").format(
name=name, namespace=namespace if namespace is not None else self.namespace
Expand All @@ -116,6 +123,7 @@ def get_event_source(self, name: str, namespace: Optional[str] = None) -> EventS
def update_event_source(
self, name: str, req: UpdateEventSourceRequest, namespace: Optional[str] = None
) -> EventSource:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.put(
url=urljoin(self.host, "api/v1/event-sources/{namespace}/{name}").format(
name=name, namespace=namespace if namespace is not None else self.namespace
Expand Down Expand Up @@ -144,6 +152,7 @@ def delete_event_source(
propagation_policy: Optional[str] = None,
dry_run: Optional[list] = None,
) -> EventSourceDeletedResponse:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.delete(
url=urljoin(self.host, "api/v1/event-sources/{namespace}/{name}").format(
name=name, namespace=namespace if namespace is not None else self.namespace
Expand All @@ -167,6 +176,7 @@ def delete_event_source(
raise Exception(f"Server returned status code {resp.status_code} with error: {resp.json()}")

def receive_event(self, discriminator: str, req: Item, namespace: Optional[str] = None) -> EventResponse:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.post(
url=urljoin(self.host, "api/v1/events/{namespace}/{discriminator}").format(
discriminator=discriminator, namespace=namespace if namespace is not None else self.namespace
Expand All @@ -185,6 +195,7 @@ def receive_event(self, discriminator: str, req: Item, namespace: Optional[str]
raise Exception(f"Server returned status code {resp.status_code} with error: {resp.json()}")

def get_info(self) -> InfoResponse:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(self.host, "api/v1/info"),
params=None,
Expand All @@ -211,6 +222,7 @@ def list_sensors(
limit: Optional[str] = None,
continue_: Optional[str] = None,
) -> SensorList:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(self.host, "api/v1/sensors/{namespace}").format(
namespace=namespace if namespace is not None else self.namespace
Expand All @@ -237,6 +249,7 @@ def list_sensors(
raise Exception(f"Server returned status code {resp.status_code} with error: {resp.json()}")

def create_sensor(self, req: CreateSensorRequest, namespace: Optional[str] = None) -> Sensor:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.post(
url=urljoin(self.host, "api/v1/sensors/{namespace}").format(
namespace=namespace if namespace is not None else self.namespace
Expand All @@ -255,6 +268,7 @@ def create_sensor(self, req: CreateSensorRequest, namespace: Optional[str] = Non
raise Exception(f"Server returned status code {resp.status_code} with error: {resp.json()}")

def get_sensor(self, name: str, namespace: Optional[str] = None, resource_version: Optional[str] = None) -> Sensor:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(self.host, "api/v1/sensors/{namespace}/{name}").format(
name=name, namespace=namespace if namespace is not None else self.namespace
Expand All @@ -271,6 +285,7 @@ def get_sensor(self, name: str, namespace: Optional[str] = None, resource_versio
raise Exception(f"Server returned status code {resp.status_code} with error: {resp.json()}")

def update_sensor(self, name: str, req: UpdateSensorRequest, namespace: Optional[str] = None) -> Sensor:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.put(
url=urljoin(self.host, "api/v1/sensors/{namespace}/{name}").format(
name=name, namespace=namespace if namespace is not None else self.namespace
Expand Down Expand Up @@ -299,6 +314,7 @@ def delete_sensor(
propagation_policy: Optional[str] = None,
dry_run: Optional[list] = None,
) -> DeleteSensorResponse:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.delete(
url=urljoin(self.host, "api/v1/sensors/{namespace}/{name}").format(
name=name, namespace=namespace if namespace is not None else self.namespace
Expand Down Expand Up @@ -334,6 +350,7 @@ def watch_event_sources(
limit: Optional[str] = None,
continue_: Optional[str] = None,
) -> EventSourceWatchEvent:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(self.host, "api/v1/stream/event-sources/{namespace}").format(
namespace=namespace if namespace is not None else self.namespace
Expand Down Expand Up @@ -377,6 +394,7 @@ def event_sources_logs(
limit_bytes: Optional[str] = None,
insecure_skip_tls_verify_backend: Optional[bool] = None,
) -> EventsourceLogEntry:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(self.host, "api/v1/stream/event-sources/{namespace}/logs").format(
namespace=namespace if namespace is not None else self.namespace
Expand Down Expand Up @@ -420,6 +438,7 @@ def watch_events(
limit: Optional[str] = None,
continue_: Optional[str] = None,
) -> Event:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(self.host, "api/v1/stream/events/{namespace}").format(
namespace=namespace if namespace is not None else self.namespace
Expand Down Expand Up @@ -458,6 +477,7 @@ def watch_sensors(
limit: Optional[str] = None,
continue_: Optional[str] = None,
) -> SensorWatchEvent:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(self.host, "api/v1/stream/sensors/{namespace}").format(
namespace=namespace if namespace is not None else self.namespace
Expand Down Expand Up @@ -500,6 +520,7 @@ def sensors_logs(
limit_bytes: Optional[str] = None,
insecure_skip_tls_verify_backend: Optional[bool] = None,
) -> SensorLogEntry:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(self.host, "api/v1/stream/sensors/{namespace}/logs").format(
namespace=namespace if namespace is not None else self.namespace
Expand Down Expand Up @@ -530,6 +551,7 @@ def sensors_logs(
raise Exception(f"Server returned status code {resp.status_code} with error: {resp.json()}")

def get_user_info(self) -> GetUserInfoResponse:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(self.host, "api/v1/userinfo"),
params=None,
Expand All @@ -544,6 +566,7 @@ def get_user_info(self) -> GetUserInfoResponse:
raise Exception(f"Server returned status code {resp.status_code} with error: {resp.json()}")

def get_version(self) -> Version:
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(self.host, "api/v1/version"),
params=None,
Expand All @@ -567,6 +590,7 @@ def get_artifact_file(
namespace: Optional[str] = None,
) -> str:
"""Get an artifact."""
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(
self.host,
Expand All @@ -592,6 +616,7 @@ def get_artifact_file(

def get_output_artifact_by_uid(self, uid: str, node_id: str, artifact_name: str) -> str:
"""Get an output artifact by UID."""
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(self.host, "artifacts-by-uid/{uid}/{nodeId}/{artifactName}").format(
uid=uid, nodeId=node_id, artifactName=artifact_name
Expand All @@ -609,6 +634,7 @@ def get_output_artifact_by_uid(self, uid: str, node_id: str, artifact_name: str)

def get_output_artifact(self, name: str, node_id: str, artifact_name: str, namespace: Optional[str] = None) -> str:
"""Get an output artifact."""
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(self.host, "artifacts/{namespace}/{name}/{nodeId}/{artifactName}").format(
name=name,
Expand All @@ -629,6 +655,7 @@ def get_output_artifact(self, name: str, node_id: str, artifact_name: str, names

def get_input_artifact_by_uid(self, uid: str, node_id: str, artifact_name: str) -> str:
"""Get an input artifact by UID."""
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(self.host, "input-artifacts-by-uid/{uid}/{nodeId}/{artifactName}").format(
uid=uid, nodeId=node_id, artifactName=artifact_name
Expand All @@ -646,6 +673,7 @@ def get_input_artifact_by_uid(self, uid: str, node_id: str, artifact_name: str)

def get_input_artifact(self, name: str, node_id: str, artifact_name: str, namespace: Optional[str] = None) -> str:
"""Get an input artifact."""
assert valid_host_scheme(self.host), "The host scheme is required for service usage"
resp = requests.get(
url=urljoin(self.host, "input-artifacts/{namespace}/{name}/{nodeId}/{artifactName}").format(
name=name,
Expand Down
Loading