Skip to content

Commit f077082

Browse files
authored
Add service selector to fluentbit spec (anvil-verifier#437)
Signed-off-by: Wenjie Ma <[email protected]>
1 parent 793f15d commit f077082

File tree

7 files changed

+99
-3
lines changed

7 files changed

+99
-3
lines changed

deploy/fluent/crd.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,6 +1840,11 @@ spec:
18401840
type: string
18411841
default: {}
18421842
type: object
1843+
serviceSelector:
1844+
additionalProperties:
1845+
type: string
1846+
nullable: true
1847+
type: object
18431848
tolerations:
18441849
items:
18451850
description: "The pod this Toleration is attached to tolerates any taint that matches the triple <key,value,effect> using the matching operator <operator>."

e2e/src/fluent_e2e.rs

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![allow(unused_imports)]
22
#![allow(unused_variables)]
3-
use k8s_openapi::api::core::v1::{Pod, ServiceAccount};
3+
use k8s_openapi::api::core::v1::{Pod, ServiceAccount, Service};
44
use k8s_openapi::api::rbac::v1::RoleBinding;
55
use k8s_openapi::api::{apps::v1::DaemonSet, rbac::v1::Role};
66
use k8s_openapi::apiextensions_apiserver::pkg::apis::apiextensions::v1::CustomResourceDefinition;
@@ -120,6 +120,7 @@ pub async fn desired_state_test(client: Client, fb_name: String) -> Result<(), E
120120
// Check daemon set
121121
let role_api: Api<Role> = Api::default_namespaced(client.clone());
122122
let rb_api: Api<RoleBinding> = Api::default_namespaced(client.clone());
123+
let svc_api: Api<Service> = Api::default_namespaced(client.clone());
123124
let sa_api: Api<ServiceAccount> = Api::default_namespaced(client.clone());
124125
let ds_api: Api<DaemonSet> = Api::default_namespaced(client.clone());
125126

@@ -150,6 +151,15 @@ pub async fn desired_state_test(client: Client, fb_name: String) -> Result<(), E
150151
_ => {}
151152
};
152153

154+
let svc = svc_api.get(&fb_name).await;
155+
match svc {
156+
Err(e) => {
157+
println!("Get service failed with error {}.", e);
158+
continue;
159+
}
160+
_ => {}
161+
}
162+
153163
let ds = ds_api.get(&fb_name).await;
154164
match ds {
155165
Err(e) => {
@@ -274,6 +284,61 @@ pub async fn relabel_test(client: Client, fb_name: String) -> Result<(), Error>
274284
Ok(())
275285
}
276286

287+
pub async fn service_selector_test(client: Client, fb_name: String) -> Result<(), Error> {
288+
let timeout = Duration::from_secs(360);
289+
let start = Instant::now();
290+
let svc_api: Api<Service> = Api::default_namespaced(client.clone());
291+
run_command(
292+
"kubectl",
293+
vec![
294+
"patch",
295+
"fb",
296+
"fluent-bit",
297+
"--type=json",
298+
"-p",
299+
"[{\"op\": \"add\", \"path\": \"/spec/serviceSelector\", \"value\": {\"never-match-anything\": \"val\"}}]",
300+
],
301+
"failed to set service selector to fb",
302+
);
303+
304+
// Sleep for extra 5 seconds to ensure the upgrading has started
305+
sleep(Duration::from_secs(5)).await;
306+
loop {
307+
sleep(Duration::from_secs(5)).await;
308+
if start.elapsed() > timeout {
309+
return Err(Error::Timeout);
310+
}
311+
312+
// Check daemon set
313+
let svc = svc_api.get(&fb_name).await;
314+
match svc {
315+
Err(e) => {
316+
println!("Get service failed with error {}.", e);
317+
continue;
318+
}
319+
Ok(svc) => {
320+
if svc
321+
.spec
322+
.as_ref()
323+
.unwrap()
324+
.selector
325+
.as_ref()
326+
.unwrap()
327+
.contains_key("never-match-anything")
328+
{
329+
println!("Selector for service is updated yet");
330+
break;
331+
} else {
332+
println!("Selector for service is not updated yet");
333+
}
334+
}
335+
};
336+
}
337+
338+
println!("Service selector test passed.");
339+
Ok(())
340+
}
341+
277342
pub async fn fluent_e2e_test() -> Result<(), Error> {
278343
// check if the CRD is already registered
279344
let client = Client::try_default().await?;
@@ -296,6 +361,7 @@ pub async fn fluent_e2e_test() -> Result<(), Error> {
296361

297362
desired_state_test(client.clone(), fb_name.clone()).await?;
298363
relabel_test(client.clone(), fb_name.clone()).await?;
364+
service_selector_test(client.clone(), fb_name.clone()).await?;
299365

300366
println!("E2e test passed.");
301367
Ok(())

src/controller_examples/fluent_controller/fluentbit/exec/resource/service.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,13 @@ pub fn make_service(fb: &FluentBit) -> (service: Service)
158158
}
159159
ports
160160
});
161-
service_spec.set_selector(make_base_labels(fb));
161+
service_spec.set_selector({
162+
if fb.spec().service_selector().is_some() {
163+
fb.spec().service_selector().unwrap()
164+
} else {
165+
make_base_labels(fb)
166+
}
167+
});
162168
service_spec
163169
});
164170
service

src/controller_examples/fluent_controller/fluentbit/model/resource/service.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,11 @@ pub open spec fn make_service(fb: FluentBitView) -> ServiceView {
117117
Some(seq![metrics_port])
118118
}
119119
},
120-
selector: Some(make_base_labels(fb)),
120+
selector: if fb.spec.service_selector.is_Some() {
121+
fb.spec.service_selector
122+
} else {
123+
Some(make_base_labels(fb))
124+
},
121125
..ServiceSpecView::default()
122126
}),
123127
..ServiceView::default()

src/controller_examples/fluent_controller/fluentbit/trusted/exec_types.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,18 @@ impl FluentBitSpec {
186186
StringMap::from_rust_map(self.inner.service_labels.clone())
187187
}
188188

189+
#[verifier(external_body)]
190+
pub fn service_selector(&self) -> (service_selector: Option<StringMap>)
191+
ensures
192+
service_selector.is_Some() == self@.service_selector.is_Some(),
193+
service_selector.is_Some() ==> service_selector.get_Some_0()@ == self@.service_selector.get_Some_0(),
194+
{
195+
match &self.inner.service_selector {
196+
Some(selector) => Some(StringMap::from_rust_map(selector.clone())),
197+
None => None,
198+
}
199+
}
200+
189201
#[verifier(external_body)]
190202
pub fn service_annotations(&self) -> (service_annotations: StringMap)
191203
ensures service_annotations@ == self@.service_annotations,

src/controller_examples/fluent_controller/fluentbit/trusted/spec_types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ pub struct FluentBitSpecView {
150150
pub annotations: Map<StringView, StringView>,
151151
pub service_account_annotations: Map<StringView, StringView>,
152152
pub service_labels: Map<StringView, StringView>,
153+
pub service_selector: Option<Map<StringView, StringView>>,
153154
pub service_annotations: Map<StringView, StringView>,
154155
pub affinity: Option<AffinityView>,
155156
pub disable_log_volumes: bool,

src/deps_hack/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ pub struct FluentBitSpec {
211211
pub service_account_annotations: std::collections::BTreeMap<String, String>,
212212
#[serde(default, rename = "serviceLabels")]
213213
pub service_labels: std::collections::BTreeMap<String, String>,
214+
#[serde(default, rename = "serviceSelector")]
215+
pub service_selector: Option<std::collections::BTreeMap<String, String>>,
214216
#[serde(default, rename = "serviceAnnotations")]
215217
pub service_annotations: std::collections::BTreeMap<String, String>,
216218
pub affinity: Option<k8s_openapi::api::core::v1::Affinity>,

0 commit comments

Comments
 (0)