Skip to content
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
20 changes: 19 additions & 1 deletion crossplane/function/proto/v1beta1/run_function.proto
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,24 @@ message RunFunctionRequest {
// did not exist, Crossplane sets the map key to an empty Resources message to
// indicate that it attempted to satisfy the request.
map<string, Resources> extra_resources = 6;

// Optional credentials that this Function may use to communicate with an
// external system.
map <string, Credentials> credentials = 7;
}

// Credentials that a Function may use to communicate with an external system.
message Credentials {
// Source of the credentials.
oneof source {
// Credential data loaded by Crossplane, for example from a Secret.
CredentialData credential_data = 1;
}
}

// CredentialData loaded by Crossplane, for example from a Secret.
message CredentialData {
map<string, bytes> data = 1;
}

// Resources represents the state of several Crossplane resources.
Expand Down Expand Up @@ -238,4 +256,4 @@ enum Severity {
// Normal results are emitted as normal events and debug logs associated
// with the composite resource.
SEVERITY_NORMAL = 3;
}
}
90 changes: 51 additions & 39 deletions crossplane/function/proto/v1beta1/run_function_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 30 additions & 2 deletions crossplane/function/proto/v1beta1/run_function_pb2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,55 @@ SEVERITY_WARNING: Severity
SEVERITY_NORMAL: Severity

class RunFunctionRequest(_message.Message):
__slots__ = ("meta", "observed", "desired", "input", "context", "extra_resources")
__slots__ = ("meta", "observed", "desired", "input", "context", "extra_resources", "credentials")
class ExtraResourcesEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: Resources
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[Resources, _Mapping]] = ...) -> None: ...
class CredentialsEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: Credentials
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[Credentials, _Mapping]] = ...) -> None: ...
META_FIELD_NUMBER: _ClassVar[int]
OBSERVED_FIELD_NUMBER: _ClassVar[int]
DESIRED_FIELD_NUMBER: _ClassVar[int]
INPUT_FIELD_NUMBER: _ClassVar[int]
CONTEXT_FIELD_NUMBER: _ClassVar[int]
EXTRA_RESOURCES_FIELD_NUMBER: _ClassVar[int]
CREDENTIALS_FIELD_NUMBER: _ClassVar[int]
meta: RequestMeta
observed: State
desired: State
input: _struct_pb2.Struct
context: _struct_pb2.Struct
extra_resources: _containers.MessageMap[str, Resources]
def __init__(self, meta: _Optional[_Union[RequestMeta, _Mapping]] = ..., observed: _Optional[_Union[State, _Mapping]] = ..., desired: _Optional[_Union[State, _Mapping]] = ..., input: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., context: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., extra_resources: _Optional[_Mapping[str, Resources]] = ...) -> None: ...
credentials: _containers.MessageMap[str, Credentials]
def __init__(self, meta: _Optional[_Union[RequestMeta, _Mapping]] = ..., observed: _Optional[_Union[State, _Mapping]] = ..., desired: _Optional[_Union[State, _Mapping]] = ..., input: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., context: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., extra_resources: _Optional[_Mapping[str, Resources]] = ..., credentials: _Optional[_Mapping[str, Credentials]] = ...) -> None: ...

class Credentials(_message.Message):
__slots__ = ("credential_data",)
CREDENTIAL_DATA_FIELD_NUMBER: _ClassVar[int]
credential_data: CredentialData
def __init__(self, credential_data: _Optional[_Union[CredentialData, _Mapping]] = ...) -> None: ...

class CredentialData(_message.Message):
__slots__ = ("data",)
class DataEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: bytes
def __init__(self, key: _Optional[str] = ..., value: _Optional[bytes] = ...) -> None: ...
DATA_FIELD_NUMBER: _ClassVar[int]
data: _containers.ScalarMap[str, bytes]
def __init__(self, data: _Optional[_Mapping[str, bytes]] = ...) -> None: ...

class Resources(_message.Message):
__slots__ = ("items",)
Expand Down
21 changes: 21 additions & 0 deletions crossplane/function/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,24 @@ def get_condition(resource: structpb.Struct, typ: str) -> Condition:
return condition

return unknown


@dataclasses.dataclass
class Credentials:
"""Credentials."""

type: str
data: dict


def get_credentials(req: structpb.Struct, name: str) -> Credentials:
"""Get the supplied credentials."""
empty = Credentials(type="data", data={})
if "credentials" not in req:
return empty
if name not in req["credentials"]:
return empty
return Credentials(
type=req["credentials"][name]["type"],
data=struct_to_dict(req["credentials"][name]["data"]),
)
Loading