Skip to content

Commit d059219

Browse files
feat: Add the product "opensearch"
1 parent 974f767 commit d059219

File tree

7 files changed

+90
-81
lines changed

7 files changed

+90
-81
lines changed

deploy/helm/stackable-cockpit/templates/roles.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ rules:
2121
- kafka.stackable.tech
2222
- nifi.stackable.tech
2323
- opa.stackable.tech
24+
- opensearch.stackable.tech
2425
- spark.stackable.tech
2526
- superset.stackable.tech
2627
- trino.stackable.tech

rust/stackable-cockpit/src/constants.rs

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,61 @@ pub const HELM_OCI_REGISTRY: &str = "oci://oci.stackable.tech/sdp-charts";
2727

2828
pub const HELM_DEFAULT_CHART_VERSION: &str = "0.0.0-dev";
2929

30-
pub const PRODUCT_NAMES: &[&str] = &[
31-
"airflow",
32-
"druid",
33-
"hbase",
34-
"hdfs",
35-
"hive",
36-
"kafka",
37-
"nifi",
38-
"opa",
39-
"spark-connect",
40-
"spark-history",
41-
"superset",
42-
"trino",
43-
"zookeeper",
30+
/// Tuple of (product name, group, version, kind)
31+
/// Group is usually "<product name>.stackable.tech".
32+
/// The version is currently hard-coded to "v1alpha1".
33+
/// Kind is usually "<product name with a capitalized first letter>Cluster".
34+
/// But there are exceptions.
35+
pub const PRODUCTS: &[(&str, &str, &str, &str)] = &[
36+
(
37+
"airflow",
38+
"airflow.stackable.tech",
39+
"v1alpha1",
40+
"AirflowCluster",
41+
),
42+
("druid", "druid.stackable.tech", "v1alpha1", "DruidCluster"),
43+
("hbase", "hbase.stackable.tech", "v1alpha1", "HbaseCluster"),
44+
("hdfs", "hdfs.stackable.tech", "v1alpha1", "HdfsCluster"),
45+
("hive", "hive.stackable.tech", "v1alpha1", "HiveCluster"),
46+
("kafka", "kafka.stackable.tech", "v1alpha1", "KafkaCluster"),
47+
("nifi", "nifi.stackable.tech", "v1alpha1", "NifiCluster"),
48+
("opa", "opa.stackable.tech", "v1alpha1", "OpaCluster"),
49+
// Kind is "OpenSearchCluster" instead of "OpensearchCluster".
50+
(
51+
"opensearch",
52+
"opensearch.stackable.tech",
53+
"v1alpha1",
54+
"OpenSearchCluster",
55+
),
56+
// Group is "spark.stackable.tech" instead of "spark-connect.stackable.tech".
57+
// Kind is "SparkConnectServer" instead of "Spark-connectCluster".
58+
(
59+
"spark-connect",
60+
"spark.stackable.tech",
61+
"v1alpha1",
62+
"SparkConnectServer",
63+
),
64+
// Group is "spark.stackable.tech" instead of "spark-history.stackable.tech".
65+
// Kind is "SparkHistoryServer" instead of "Spark-historyCluster".
66+
(
67+
"spark-history",
68+
"spark.stackable.tech",
69+
"v1alpha1",
70+
"SparkHistoryServer",
71+
),
72+
(
73+
"superset",
74+
"superset.stackable.tech",
75+
"v1alpha1",
76+
"SupersetCluster",
77+
),
78+
("trino", "trino.stackable.tech", "v1alpha1", "TrinoCluster"),
79+
(
80+
"zookeeper",
81+
"zookeeper.stackable.tech",
82+
"v1alpha1",
83+
"ZookeeperCluster",
84+
),
4485
];
4586

4687
pub const OCI_INDEX_PAGE_SIZE: usize = 20;

rust/stackable-cockpit/src/platform/operator/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub const VALID_OPERATORS: &[&str] = &[
2626
"listener",
2727
"nifi",
2828
"opa",
29+
"opensearch",
2930
"secret",
3031
"spark-k8s",
3132
"superset",
@@ -92,9 +93,10 @@ impl FromStr for OperatorSpec {
9293
ensure!(len <= 2, InvalidEqualSignCountSnafu);
9394

9495
// Check if the provided operator name is in the list of valid operators
95-
ensure!(VALID_OPERATORS.contains(&parts[0]), InvalidNameSnafu {
96-
name: parts[0]
97-
});
96+
ensure!(
97+
VALID_OPERATORS.contains(&parts[0]),
98+
InvalidNameSnafu { name: parts[0] }
99+
);
98100

99101
// If there is only one part, the input didn't include
100102
// the optional version identifier

rust/stackable-cockpit/src/platform/stacklet/mod.rs

Lines changed: 24 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
use indexmap::IndexMap;
22
use kube::{ResourceExt, core::GroupVersionKind};
33
use serde::Serialize;
4-
use snafu::{ResultExt, Snafu};
4+
use snafu::{OptionExt, ResultExt, Snafu};
55
use stackable_operator::status::condition::ClusterCondition;
66
use tracing::info;
77
#[cfg(feature = "openapi")]
88
use utoipa::ToSchema;
99

1010
use crate::{
11-
constants::PRODUCT_NAMES,
11+
constants::PRODUCTS,
1212
platform::{credentials, service},
13-
utils::{
14-
k8s::{self, Client, ConditionsExt},
15-
string::Casing,
16-
},
13+
utils::k8s::{self, Client, ConditionsExt},
1714
};
1815

1916
mod grafana;
@@ -58,6 +55,9 @@ pub enum Error {
5855

5956
#[snafu(display("failed to receive service information"))]
6057
ServiceFetch { source: service::Error },
58+
59+
#[snafu(display("product name {product_name:?} not found"))]
60+
GetProduct { product_name: String },
6161
}
6262

6363
/// Lists all installed stacklets. If `namespace` is [`None`], stacklets from ALL
@@ -83,7 +83,7 @@ pub async fn get_credentials_for_product(
8383
object_name: &str,
8484
product_name: &str,
8585
) -> Result<Option<credentials::Credentials>, Error> {
86-
let product_gvk = gvk_from_product_name(product_name);
86+
let product_gvk = gvk_from_product_name(product_name)?;
8787
let product_cluster = match client
8888
.get_namespaced_object(namespace, object_name, &product_gvk)
8989
.await
@@ -113,10 +113,14 @@ async fn list_stackable_stacklets(
113113
client: &Client,
114114
namespace: Option<&str>,
115115
) -> Result<Vec<Stacklet>, Error> {
116-
let product_list = build_products_gvk_list(PRODUCT_NAMES);
117116
let mut stacklets = Vec::new();
118117

119-
for (product_name, product_gvk) in product_list {
118+
for (product_name, group, version, kind) in PRODUCTS {
119+
let product_gvk = GroupVersionKind {
120+
group: group.to_string(),
121+
version: version.to_string(),
122+
kind: kind.to_string(),
123+
};
120124
let objects = match client
121125
.list_objects(&product_gvk, namespace)
122126
.await
@@ -164,42 +168,15 @@ async fn list_stackable_stacklets(
164168
Ok(stacklets)
165169
}
166170

167-
fn build_products_gvk_list<'a>(product_names: &[&'a str]) -> IndexMap<&'a str, GroupVersionKind> {
168-
let mut map = IndexMap::new();
169-
170-
for product_name in product_names {
171-
// Note(techassi): Why? Just why? Can we please make this consistent?
172-
// Note(sbernauer): I think it's legit that SparkHistoryServer and SparkConnectServer are in
173-
// the api group spark.stackable.tech. All of this will probably be rewritten any as soon as
174-
// we have versions different than v1alpha1.
175-
if *product_name == "spark-history" {
176-
map.insert(*product_name, GroupVersionKind {
177-
group: "spark.stackable.tech".into(),
178-
version: "v1alpha1".into(),
179-
kind: "SparkHistoryServer".into(),
180-
});
181-
} else if *product_name == "spark-connect" {
182-
map.insert(*product_name, GroupVersionKind {
183-
group: "spark.stackable.tech".into(),
184-
version: "v1alpha1".into(),
185-
kind: "SparkConnectServer".into(),
186-
});
187-
} else {
188-
map.insert(*product_name, gvk_from_product_name(product_name));
189-
}
190-
}
191-
192-
map
193-
}
194-
195-
// FIXME: Support SparkApplication and SparkConnectServer
196-
fn gvk_from_product_name(product_name: &str) -> GroupVersionKind {
197-
GroupVersionKind {
198-
group: format!("{product_name}.stackable.tech"),
199-
version: "v1alpha1".into(),
200-
kind: format!(
201-
"{product_name}Cluster",
202-
product_name = product_name.capitalize()
203-
),
204-
}
171+
fn gvk_from_product_name(product_name: &str) -> Result<GroupVersionKind, Error> {
172+
let (_, group, version, kind) = PRODUCTS
173+
.iter()
174+
.find(|(other_product_name, _, _, _)| product_name == *other_product_name)
175+
.context(GetProductSnafu { product_name })?;
176+
177+
Ok(GroupVersionKind {
178+
group: group.to_string(),
179+
version: version.to_string(),
180+
kind: kind.to_string(),
181+
})
205182
}

rust/stackable-cockpit/src/utils/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ pub mod check;
33
pub mod k8s;
44
pub mod params;
55
pub mod path;
6-
pub mod string;
76
pub mod templating;
87

98
/// Returns the name of the operator used in the Helm repository.

rust/stackable-cockpit/src/utils/string.rs

Lines changed: 0 additions & 16 deletions
This file was deleted.

rust/stackablectl/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44

55
## [Unreleased]
66

7+
### Added
8+
9+
- Add OpenSearch to the list of supported products ([#400]).
10+
711
### Fixed
812

913
- nix: Update nixpkgs and upgrade nodejs-18 to nodejs_20 ([#384]).
@@ -15,6 +19,7 @@ All notable changes to this project will be documented in this file.
1519
[#384]: https://github.com/stackabletech/stackable-cockpit/pull/384
1620
[#386]: https://github.com/stackabletech/stackable-cockpit/pull/386
1721
[#388]: https://github.com/stackabletech/stackable-cockpit/pull/388
22+
[#400]: https://github.com/stackabletech/stackable-cockpit/pull/400
1823

1924
## [1.0.0] - 2025-06-02
2025

0 commit comments

Comments
 (0)