-
-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathmod.rs
More file actions
170 lines (150 loc) · 6.02 KB
/
Copy pathmod.rs
File metadata and controls
170 lines (150 loc) · 6.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
use kube::CustomResource;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::{commons::tls_verification::TlsClientDetails, versioned::versioned};
mod v1alpha1_impl;
// FIXME (@Techassi): This should be versioned as well, but the macro cannot
// handle new-type structs yet.
/// Use this type in your operator!
pub type ResolvedOpenLineageConnection = v1alpha1::OpenLineageConnectionSpec;
#[versioned(
version(name = "v1alpha1"),
crates(
kube_core = "kube::core",
k8s_openapi = "k8s_openapi",
schemars = "schemars",
)
)]
pub mod versioned {
pub mod v1alpha1 {
pub use v1alpha1_impl::OpenLineageError;
}
/// OpenLineage connection definition as a resource.
/// Learn more about [OpenLineage](https://openlineage.io/).
#[versioned(crd(
group = "lineage.stackable.tech",
kind = "OpenLineageConnection",
plural = "openlineageconnections",
doc = "A reusable definition of a connection to an OpenLineage backend.",
namespaced
))]
#[derive(CustomResource, Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct OpenLineageConnectionSpec {
/// Host of the OpenLineage backend without any protocol or port. For example: `marquez`.
pub host: String,
/// Port the OpenLineage backend listens on. For example: `5000`.
pub port: u16,
/// Use a TLS connection. If not specified no TLS will be used.
/// When TLS server verification is configured, the transport uses `https` instead of `http`.
#[serde(flatten)]
pub tls: TlsClientDetails,
/// Name of a Secret containing the API key used to authenticate against the OpenLineage
/// backend. The API key must be stored under the key `apiKey`. The Secret must be located in
/// the same namespace as the workload using this connection. If not specified, no
/// authentication is used.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub credentials_secret_name: Option<String>,
}
/// An OpenLineage connection, either inlined or referenced by the name of an
/// [`OpenLineageConnection`] resource in the same namespace.
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
// TODO: This probably should be serde(untagged), but this would be a breaking change
pub enum InlineConnectionOrReference {
Inline(OpenLineageConnectionSpec),
Reference(String),
}
/// OpenLineage lineage-emission configuration for a single workload/application.
///
/// Embed this in an operator's workload spec to enable OpenLineage for that workload.
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct OpenLineageJob {
/// The OpenLineage backend connection, either inlined or referencing an
/// `OpenLineageConnection` resource by name.
pub connection: InlineConnectionOrReference,
/// The OpenLineage namespace lineage is reported under.
/// If unset, operators typically default to the workload's Kubernetes namespace.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub namespace: Option<String>,
/// A stable OpenLineage job name. Setting this prevents fragmented run history.
/// If unset, operators resolve a name from workload-specific configuration.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub job_name: Option<String>,
}
}
#[cfg(test)]
impl stackable_versioned::test_utils::RoundtripTestData for v1alpha1::OpenLineageConnectionSpec {
fn roundtrip_test_data() -> Vec<Self> {
crate::utils::yaml_from_str_singleton_map(indoc::indoc! {"
- host: marquez
port: 5000
- host: marquez
port: 5000
tls:
verification:
none: {}
- host: marquez
port: 5000
tls:
verification:
server:
caCert:
secretClass: openlineage-cert
- host: marquez
port: 5000
credentialsSecretName: openlineage-credentials
"})
.expect("Failed to parse OpenLineageConnectionSpec YAML")
}
}
#[cfg(test)]
mod tests {
use crate::{
commons::tls_verification::{
CaCert, Tls, TlsClientDetails, TlsServerVerification, TlsVerification,
},
crd::openlineage::v1alpha1::OpenLineageConnectionSpec,
};
#[test]
fn http_transport_url_without_tls() {
let connection = OpenLineageConnectionSpec {
host: "marquez".to_string(),
port: 5000,
tls: TlsClientDetails { tls: None },
credentials_secret_name: None,
};
assert_eq!(connection.transport_url(), "http://marquez:5000");
}
#[test]
fn https_transport_url_with_server_verification() {
let connection = OpenLineageConnectionSpec {
host: "marquez".to_string(),
port: 5000,
tls: TlsClientDetails {
tls: Some(Tls {
verification: TlsVerification::Server(TlsServerVerification {
ca_cert: CaCert::WebPki {},
}),
}),
},
credentials_secret_name: None,
};
assert_eq!(connection.transport_url(), "https://marquez:5000");
}
#[test]
fn http_transport_url_without_verification() {
let connection = OpenLineageConnectionSpec {
host: "marquez".to_string(),
port: 5000,
tls: TlsClientDetails {
tls: Some(Tls {
verification: TlsVerification::None {},
}),
},
credentials_secret_name: None,
};
assert_eq!(connection.transport_url(), "http://marquez:5000");
}
}