Skip to content

Commit c7313a8

Browse files
committed
Revert "fix: make application templates namespaced (#694)" (#719)
* Revert "fix: make application templates namespaced (#694)" This reverts commit b326be3. * revert changelog * update nix crate hashes
1 parent 43235f5 commit c7313a8

7 files changed

Lines changed: 22 additions & 140 deletions

File tree

CHANGELOG.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ All notable changes to this project will be documented in this file.
3131
- Internal operator refactoring: introduce dereference() and validate() steps in the reconciler for spark application, spark connect and spark history server([#687]).
3232
- test: Bump vector-aggregator to 0.55.0, replace /graphql call with gRPC call ([#689]).
3333
- Fix the `SparkApplication` CRD description, which incorrectly described it as a "Spark cluster stacklet" rather than a Spark application ([#705]).
34-
- BREAKING: make application templates namespaced instead of cluster wide objects ([#694]).
3534

3635
[#674]: https://github.com/stackabletech/spark-k8s-operator/pull/674
3736
[#679]: https://github.com/stackabletech/spark-k8s-operator/pull/679
@@ -40,7 +39,6 @@ All notable changes to this project will be documented in this file.
4039
[#687]: https://github.com/stackabletech/spark-k8s-operator/pull/687
4140
[#689]: https://github.com/stackabletech/spark-k8s-operator/pull/689
4241
[#692]: https://github.com/stackabletech/spark-k8s-operator/pull/692
43-
[#694]: https://github.com/stackabletech/spark-k8s-operator/pull/694
4442
[#696]: https://github.com/stackabletech/spark-k8s-operator/pull/696
4543
[#705]: https://github.com/stackabletech/spark-k8s-operator/pull/705
4644
[#708]: https://github.com/stackabletech/spark-k8s-operator/pull/708

Cargo.nix

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crate-hashes.json

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/modules/spark-k8s/pages/usage-guide/app_templates.adoc

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,13 @@ Spark application templates are used to define reusable configurations for Spark
55
When you have many applications with similar configurations, templates can help you avoid duplication by grouping common settings together.
66
Application templates are available for the `v1alpha1` version of the SparkApplication custom resource and share the exact same structure as the SparkApplication resource, but with some differences in the way the operator handles them:
77

8-
1. Application templates are namespace-scoped resources, just like Spark applications.
9-
This means that a SparkApplication can only reference templates from its own namespace.
8+
1. Application templates are cluster wide resources, while Spark application resources are namespace-scoped.
9+
This means that application templates can be used across multiple namespaces, while Spark application resources are limited to the namespace they are created in.
1010
2. Application templates are not reconciled by the operator, but must be referenced from a SparkApplication resource to be applied. This means that changes to an application template will not automatically trigger updates to SparkApplication resources that reference it.
1111
3. An application can reference multiple application templates, and the settings from these templates will be merged together. The merging order of the templates is indicated by their index in the reference list. The application fields have the highest precedence and will override any conflicting settings from the templates. This allows you to have a base template with common settings and then override specific settings in the application resource as needed.
1212
4. Application template references are immutable in the sense that once applied to an application they cannot be changed again. Currently templates are applied upon the creation of the application, and any changes to the template references after that will be ignored.
1313
5. Application and template CRDs must have the exact same versions. Currently only `v1alpha1` is supported.
1414
15-
== Migrating from cluster-scoped templates
16-
17-
IMPORTANT: Application templates used to be cluster wide resources when they were first released. This was a mistake. Many users do not have the access rights to create cluster scoped resources and so the templates are now namespace scoped.
18-
19-
If you are migrating from older installations where templates were treated as cluster-wide resources, account for the following:
20-
21-
1. Recreate each template in every namespace where SparkApplications use it.
22-
2. Keep template names consistent per namespace if you want the same application annotations to continue working.
23-
3. Cross-namespace template references are no longer resolved; templates and applications must be in the same namespace.
24-
4. Update GitOps/automation manifests to create templates as namespace-targeted resources before reconciling dependent SparkApplications.
2515
== Examples
2616

2717
Applications use `metadata.annotations` to reference application templates as shown below:

extra/crds.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4657,7 +4657,7 @@ spec:
46574657
shortNames:
46584658
- sparkapptemplate
46594659
singular: sparkapplicationtemplate
4660-
scope: Namespaced
4660+
scope: Cluster
46614661
versions:
46624662
- additionalPrinterColumns: []
46634663
name: v1alpha1

rust/operator-binary/src/crd/template_merger.rs

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -322,47 +322,6 @@ mod tests {
322322
assert_eq!(merged.spec.args, vec!["arg1", "arg2"]);
323323
}
324324

325-
#[test]
326-
fn test_deep_merge_metadata_namespace_overlay_wins() {
327-
let base = serde_yaml::from_str::<crate::crd::v1alpha1::SparkApplication>(indoc! {r#"
328-
---
329-
apiVersion: spark.stackable.tech/v1alpha1
330-
kind: SparkApplication
331-
metadata:
332-
name: base-app
333-
namespace: template-namespace
334-
spec:
335-
mode: cluster
336-
mainApplicationFile: base.py
337-
sparkImage:
338-
productVersion: "3.5.0"
339-
"#})
340-
.unwrap();
341-
342-
let overlay = serde_yaml::from_str::<crate::crd::v1alpha1::SparkApplication>(indoc! {r#"
343-
---
344-
apiVersion: spark.stackable.tech/v1alpha1
345-
kind: SparkApplication
346-
metadata:
347-
name: overlay-app
348-
namespace: app-namespace
349-
spec:
350-
mode: cluster
351-
mainApplicationFile: overlay.py
352-
sparkImage:
353-
productVersion: "3.5.1"
354-
"#})
355-
.unwrap();
356-
357-
let merged = deep_merge(&base, &overlay);
358-
359-
assert_eq!(
360-
merged.metadata.namespace,
361-
Some("app-namespace".to_string()),
362-
"overlay namespace should take precedence"
363-
);
364-
}
365-
366325
#[test]
367326
fn test_deep_merge_spark_conf() {
368327
let base = serde_yaml::from_str::<crate::crd::v1alpha1::SparkApplication>(indoc! {r#"

rust/operator-binary/src/crd/template_spec.rs

Lines changed: 1 addition & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,6 @@ pub enum Error {
4444
template_name: String,
4545
source: stackable_operator::kube::Error,
4646
},
47-
48-
#[snafu(display("object has no namespace"))]
49-
ObjectHasNoNamespace,
5047
}
5148

5249
#[versioned(
@@ -69,7 +66,6 @@ pub mod versioned {
6966
group = "spark.stackable.tech",
7067
plural = "sparkapptemplates",
7168
shortname = "sparkapptemplate",
72-
namespaced
7369
))]
7470
#[derive(Clone, CustomResource, Debug, Deserialize, JsonSchema, Serialize)]
7571
#[serde(rename_all = "camelCase")]
@@ -267,10 +263,8 @@ pub(crate) async fn merge_application_templates(
267263
// In the future if we support additional strategies in addition to "enforce",
268264
// this list might not be identical to the one in `merge_template_options`
269265
// because some objects might be missing.
270-
let namespace = spark_application_namespace(spark_application)?;
271266
let templates = resolve(
272267
client,
273-
namespace,
274268
&merge_template_options.template_names,
275269
merge_template_options.apply_strategy,
276270
)
@@ -323,28 +317,16 @@ pub(crate) async fn merge_application_templates(
323317
Ok(default_result)
324318
}
325319

326-
fn spark_application_namespace(
327-
spark_application: &super::v1alpha1::SparkApplication,
328-
) -> Result<&str, Error> {
329-
spark_application
330-
.metadata
331-
.namespace
332-
.as_deref()
333-
.ok_or(Error::ObjectHasNoNamespace)
334-
}
335-
336320
async fn resolve(
337321
client: &stackable_operator::client::Client,
338-
namespace: &str,
339322
template_names: &[String],
340323
apply_strategy: TemplateApplyStrategy,
341324
) -> Result<Vec<v1alpha1::SparkApplicationTemplate>, Error> {
342325
if template_names.is_empty() {
343326
return Ok(vec![]);
344327
}
345328

346-
let templates_api =
347-
Api::<v1alpha1::SparkApplicationTemplate>::namespaced(client.as_kube_client(), namespace);
329+
let templates_api = Api::<v1alpha1::SparkApplicationTemplate>::all(client.as_kube_client());
348330
let mut resolved_templates = Vec::new();
349331
for template_name in template_names {
350332
let template_res = templates_api
@@ -452,53 +434,6 @@ mod tests {
452434
assert!(options.template_names.is_empty());
453435
}
454436

455-
#[test]
456-
fn spark_application_namespace_returns_namespace() {
457-
let spark_application =
458-
serde_yaml::from_str::<crate::crd::v1alpha1::SparkApplication>(indoc! {r#"
459-
---
460-
apiVersion: spark.stackable.tech/v1alpha1
461-
kind: SparkApplication
462-
metadata:
463-
name: app-with-templates
464-
namespace: default
465-
spec:
466-
mode: cluster
467-
mainApplicationFile: local:///app.py
468-
sparkImage:
469-
productVersion: "3.5.8"
470-
"#})
471-
.unwrap();
472-
473-
assert_eq!(
474-
spark_application_namespace(&spark_application).unwrap(),
475-
"default"
476-
);
477-
}
478-
479-
#[test]
480-
fn spark_application_namespace_returns_error_when_missing() {
481-
let spark_application =
482-
serde_yaml::from_str::<crate::crd::v1alpha1::SparkApplication>(indoc! {r#"
483-
---
484-
apiVersion: spark.stackable.tech/v1alpha1
485-
kind: SparkApplication
486-
metadata:
487-
name: app-with-templates
488-
spec:
489-
mode: cluster
490-
mainApplicationFile: local:///app.py
491-
sparkImage:
492-
productVersion: "3.5.8"
493-
"#})
494-
.unwrap();
495-
496-
assert!(matches!(
497-
spark_application_namespace(&spark_application),
498-
Err(Error::ObjectHasNoNamespace)
499-
));
500-
}
501-
502437
impl RoundtripTestData for v1alpha1::SparkApplicationTemplateSpec {
503438
fn roundtrip_test_data() -> Vec<Self> {
504439
// SparkApplicationTemplateSpec is just a wrapper around SparkApplicationSpec

0 commit comments

Comments
 (0)