-
-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathopa.rs
More file actions
136 lines (127 loc) · 5.3 KB
/
Copy pathopa.rs
File metadata and controls
136 lines (127 loc) · 5.3 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
use std::collections::BTreeMap;
use stackable_operator::{
client::Client,
commons::opa::{OpaApiVersion, OpaConfig},
k8s_openapi::api::core::v1::ConfigMap,
kube::ResourceExt,
};
use crate::crd::v1alpha1::TrinoCluster;
pub const OPA_TLS_VOLUME_NAME: &str = "opa-tls";
pub struct TrinoOpaConfig {
/// URI for OPA policies, e.g.
/// `http://localhost:8081/v1/data/trino/allow`
pub(crate) non_batched_connection_string: String,
/// URI for Batch OPA policies, e.g.
/// `http://localhost:8081/v1/data/trino/batch` - if not set, a
/// single request will be sent for each entry on filtering methods
pub(crate) batched_connection_string: String,
/// URI for fetching row filters, e.g.
/// `http://localhost:8081/v1/data/trino/rowFilters` - if not set,
/// no row filtering will be applied
pub(crate) row_filters_connection_string: Option<String>,
/// URI for fetching column masks, e.g.
/// `http://localhost:8081/v1/data/trino/columnMask` - if not set,
/// no masking will be applied
pub(crate) column_masking_connection_string: Option<String>,
/// Whether to allow permission management (GRANT, DENY, ...) and
/// role management operations - OPA will not be queried for any
/// such operations, they will be bulk allowed or denied depending
/// on this setting
pub(crate) allow_permission_management_operations: bool,
/// Optional TLS secret class for OPA communication.
/// If set, the CA certificate from this secret class will be added
/// to Trino's truststore to make it trust OPA's TLS certificate.
pub(crate) tls_secret_class: Option<String>,
}
impl TrinoOpaConfig {
pub async fn from_opa_config(
client: &Client,
trino: &TrinoCluster,
opa_config: &OpaConfig,
) -> Result<Self, stackable_operator::commons::opa::Error> {
let non_batched_connection_string = opa_config
.full_document_url_from_config_map(client, trino, Some("allow"), OpaApiVersion::V1)
.await?;
let batched_connection_string = opa_config
.full_document_url_from_config_map(
client,
trino,
// Sticking to example https://trino.io/docs/current/security/opa-access-control.html
Some("batch"),
OpaApiVersion::V1,
)
.await?;
let row_filters_connection_string = opa_config
.full_document_url_from_config_map(
client,
trino,
// Sticking to https://github.com/trinodb/trino/blob/455/plugin/trino-opa/src/test/java/io/trino/plugin/opa/TestOpaAccessControlDataFilteringSystem.java#L46
Some("rowFilters"),
OpaApiVersion::V1,
)
.await?;
let column_masking_connection_string = opa_config
.full_document_url_from_config_map(
client,
trino,
// Sticking to https://github.com/trinodb/trino/blob/455/plugin/trino-opa/src/test/java/io/trino/plugin/opa/TestOpaAccessControlDataFilteringSystem.java#L47
Some("columnMask"),
OpaApiVersion::V1,
)
.await?;
let tls_secret_class = client
.get::<ConfigMap>(
&opa_config.config_map_name,
trino.namespace().as_deref().unwrap_or("default"),
)
.await
.ok()
.and_then(|cm| cm.data)
.and_then(|mut data| data.remove("OPA_SECRET_CLASS"));
Ok(TrinoOpaConfig {
non_batched_connection_string,
batched_connection_string,
row_filters_connection_string: Some(row_filters_connection_string),
column_masking_connection_string: Some(column_masking_connection_string),
allow_permission_management_operations: true,
tls_secret_class,
})
}
pub fn as_config(&self) -> BTreeMap<String, Option<String>> {
let mut config = BTreeMap::from([
("access-control.name".to_string(), Some("opa".to_string())),
(
"opa.policy.uri".to_string(),
Some(self.non_batched_connection_string.clone()),
),
(
"opa.policy.batched-uri".to_string(),
Some(self.batched_connection_string.clone()),
),
]);
if let Some(row_filters_connection_string) = &self.row_filters_connection_string {
config.insert(
"opa.policy.row-filters-uri".to_string(),
Some(row_filters_connection_string.clone()),
);
}
if let Some(column_masking_connection_string) = &self.column_masking_connection_string {
config.insert(
"opa.policy.column-masking-uri".to_string(),
Some(column_masking_connection_string.clone()),
);
}
if self.allow_permission_management_operations {
config.insert(
"opa.allow-permission-management-operations".to_string(),
Some("true".to_string()),
);
}
config
}
pub fn tls_mount_path(&self) -> Option<String> {
self.tls_secret_class
.as_ref()
.map(|_| format!("/stackable/secrets/{OPA_TLS_VOLUME_NAME}"))
}
}