Skip to content

Commit 6430219

Browse files
committed
Support specifying Service type
1 parent 8a88110 commit 6430219

File tree

9 files changed

+65
-10
lines changed

9 files changed

+65
-10
lines changed

CHANGELOG.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,13 @@ All notable changes to this project will be documented in this file.
1212

1313
### Changed
1414

15-
- `operator-rs` `0.36.0` -> `0.39.0` ([#326], [#337]).
1615
- [Breaking] Moved top level config option to `clusterConfig` ([#326]).
16+
- [BREAKING] Support specifying Service type.
17+
This enables us to later switch non-breaking to using `ListenerClasses` for the exposure of Services.
18+
This change is breaking, because - for security reasons - we default to the `cluster-internal` `ListenerClass`.
19+
If you need you cluster to be accessible from outside of Kubernetes you need to set `clusterConfig.listenerClass`
20+
to `external-unstable` ([#XXX]).
21+
- `operator-rs` `0.36.0` -> `0.39.0` ([#326], [#337]).
1722

1823
### Removed
1924

rust/crd/src/lib.rs

+42-3
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,39 @@ pub struct HdfsClusterConfig {
9090
pub vector_aggregator_config_map_name: Option<String>,
9191
/// Name of the ZooKeeper discovery config map.
9292
pub zookeeper_config_map_name: String,
93+
/// In the future this setting will control, which ListenerClass <https://docs.stackable.tech/home/stable/listener-operator/listenerclass.html>
94+
/// will be used to expose the service.
95+
/// Currently only a subset of the ListenerClasses are supported by choosing the type of the created Services
96+
/// by looking at the ListenerClass name specified,
97+
/// In a future release support for custom ListenerClasses will be introduced without a breaking change:
98+
///
99+
/// * cluster-internal: Use a ClusterIP service
100+
///
101+
/// * external-unstable: Use a NodePort service
102+
#[serde(default)]
103+
pub listener_class: CurrentlySupportedListenerClasses,
104+
}
105+
106+
// TODO: Temporary solution until listener-operator is finished
107+
#[derive(
108+
Clone, Debug, Default, Display, Deserialize, Eq, Hash, JsonSchema, PartialEq, Serialize,
109+
)]
110+
#[serde(rename_all = "PascalCase")]
111+
pub enum CurrentlySupportedListenerClasses {
112+
#[default]
113+
#[serde(rename = "cluster-internal")]
114+
ClusterInternal,
115+
#[serde(rename = "external-unstable")]
116+
ExternalUnstable,
117+
}
118+
119+
impl CurrentlySupportedListenerClasses {
120+
pub fn k8s_service_type(&self) -> String {
121+
match self {
122+
CurrentlySupportedListenerClasses::ClusterInternal => "ClusterIP".to_string(),
123+
CurrentlySupportedListenerClasses::ExternalUnstable => "NodePort".to_string(),
124+
}
125+
}
93126
}
94127

95128
/// This is a shared trait for all role/role-group config structs to avoid duplication
@@ -433,9 +466,15 @@ impl HdfsCluster {
433466
);
434467
group_labels.insert(String::from("role"), rolegroup_ref.role.clone());
435468
group_labels.insert(String::from("group"), rolegroup_ref.role_group.clone());
436-
// TODO: in a production environment, probably not all roles need to be exposed with one NodePort per Pod but it's
437-
// useful for development purposes.
438-
group_labels.insert(LABEL_ENABLE.to_string(), "true".to_string());
469+
470+
if self.spec.cluster_config.listener_class
471+
== CurrentlySupportedListenerClasses::ExternalUnstable
472+
{
473+
// TODO: in a production environment, probably not all roles need to be exposed with one NodePort per Pod but it's
474+
// useful for development purposes.
475+
476+
group_labels.insert(LABEL_ENABLE.to_string(), "true".to_string());
477+
}
439478

440479
group_labels
441480
}

rust/operator/src/hdfs_controller.rs

+2
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,8 @@ fn rolegroup_service(
338338
.with_label("prometheus.io/scrape", "true")
339339
.build(),
340340
spec: Some(ServiceSpec {
341+
// Internal communication does not need to be exposed
342+
type_: Some("ClusterIP".to_string()),
341343
cluster_ip: Some("None".to_string()),
342344
ports: Some(
343345
role.ports()

tests/templates/kuttl/smoke/01-install-zk.yaml.j2

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ spec:
77
image:
88
productVersion: "{{ test_scenario['values']['zookeeper'].split('-stackable')[0] }}"
99
stackableVersion: "{{ test_scenario['values']['zookeeper'].split('-stackable')[1] }}"
10-
{% if lookup('env', 'VECTOR_AGGREGATOR') %}
1110
clusterConfig:
11+
listenerClass: {{ test_scenario['values']['listener-class'] }}
12+
{% if lookup('env', 'VECTOR_AGGREGATOR') %}
1213
logging:
1314
vectorAggregatorConfigMapName: vector-aggregator-discovery
1415
{% endif %}

tests/templates/kuttl/smoke/02-install-hdfs.yaml.j2

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ spec:
1616
clusterConfig:
1717
dfsReplication: 1
1818
zookeeperConfigMapName: hdfs-zk
19+
listenerClass: {{ test_scenario['values']['listener-class'] }}
1920
{% if lookup('env', 'VECTOR_AGGREGATOR') %}
2021
vectorAggregatorConfigMapName: vector-aggregator-discovery
2122
{% endif %}

tests/templates/kuttl/smoke/04-assert.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
apiVersion: kuttl.dev/v1beta1
33
kind: TestAssert
44
commands:
5-
- script: kubectl exec -n $NAMESPACE webhdfs-0 -- python /tmp/webhdfs.py ls
5+
- script: kubectl exec -n $NAMESPACE webhdfs-0 -- python /tmp/webhdfs.py $NAMESPACE ls

tests/templates/kuttl/smoke/04-create-file.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ kind: TestStep
44
commands:
55
- script: kubectl cp -n $NAMESPACE ./webhdfs.py webhdfs-0:/tmp
66
- script: kubectl cp -n $NAMESPACE ./testdata.txt webhdfs-0:/tmp
7-
- script: kubectl exec -n $NAMESPACE webhdfs-0 -- python /tmp/webhdfs.py create
7+
- script: kubectl exec -n $NAMESPACE webhdfs-0 -- python /tmp/webhdfs.py $NAMESPACE create

tests/templates/kuttl/smoke/webhdfs.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66
def main() -> int:
77
result = 0
8-
command = sys.argv[1]
8+
namespace = sys.argv[1]
9+
command = sys.argv[2]
910

1011
log_level = "DEBUG"
1112
logging.basicConfig(
@@ -16,7 +17,7 @@ def main() -> int:
1617

1718
if command == "ls":
1819
http_code = requests.get(
19-
"http://hdfs-namenode-default-0:9870/webhdfs/v1/testdata.txt?user.name=stackable&op=LISTSTATUS"
20+
f"http://hdfs-namenode-default-0.hdfs-namenode-default.{namespace}.svc.cluster.local:9870/webhdfs/v1/testdata.txt?user.name=stackable&op=LISTSTATUS"
2021
).status_code
2122
if http_code != 200:
2223
result = 1
@@ -30,7 +31,7 @@ def main() -> int:
3031
)
3132
}
3233
http_code = requests.put(
33-
"http://hdfs-namenode-default-0:9870/webhdfs/v1/testdata.txt?user.name=stackable&op=CREATE",
34+
f"http://hdfs-namenode-default-0.hdfs-namenode-default.{namespace}.svc.cluster.local:9870/webhdfs/v1/testdata.txt?user.name=stackable&op=CREATE",
3435
files=files,
3536
allow_redirects=True,
3637
).status_code

tests/test-definition.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,19 @@ dimensions:
2222
values:
2323
- "default"
2424
- "2hdd-1ssd"
25+
# Used for both, zookeeper and hdfs
26+
- name: listener-class
27+
values:
28+
- "cluster-internal"
29+
- "external-unstable"
2530
tests:
2631
- name: smoke
2732
dimensions:
2833
- hadoop
2934
- zookeeper
3035
- number-of-datanodes
3136
- datanode-pvcs
37+
- listener-class
3238
- name: orphaned-resources
3339
dimensions:
3440
- hadoop-latest

0 commit comments

Comments
 (0)