Skip to content

Commit 2c8bb1b

Browse files
authoredFeb 26, 2025··
Adds actuator Service for each integration route (#28)
* Adds actuator Service for each integration route
1 parent 839dda6 commit 2c8bb1b

File tree

7 files changed

+144
-22
lines changed

7 files changed

+144
-22
lines changed
 

‎minimal-app/pom.xml

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
<groupId>com.octo.keip</groupId>
1313
<artifactId>minimal-app</artifactId>
14-
<version>0.0.3</version>
14+
<version>0.0.4</version>
1515

1616
<properties>
1717
<docker.registry>ghcr.io/octoconsulting</docker.registry>
@@ -59,6 +59,10 @@
5959
<groupId>org.springframework.boot</groupId>
6060
<artifactId>spring-boot-starter-actuator</artifactId>
6161
</dependency>
62+
<dependency>
63+
<groupId>io.micrometer</groupId>
64+
<artifactId>micrometer-registry-prometheus</artifactId>
65+
</dependency>
6266
<dependency>
6367
<groupId>org.springframework.cloud</groupId>
6468
<artifactId>spring-cloud-starter-kubernetes-client-config</artifactId>

‎operator/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION ?= 0.5.0
1+
VERSION ?= 0.6.0
22
GIT_TAG := operator_v$(VERSION)
33
KEIP_INTEGRATION_IMAGE ?= ghcr.io/octoconsulting/keip/minimal-app:latest
44

‎operator/controller/integrationroute-controller.yaml

+9-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ spec:
2222
conditions:
2323
- type: Ready
2424
status: "True"
25+
- apiVersion: v1
26+
resource: services
27+
updateStrategy:
28+
method: RollingRecreate
29+
statusChecks:
30+
conditions:
31+
- type: Ready
32+
status: "True"
2533
hooks:
2634
sync:
2735
webhook:
@@ -50,7 +58,7 @@ spec:
5058
spec:
5159
containers:
5260
- name: webhook
53-
image: ghcr.io/octoconsulting/keip/route-webhook:0.9.0
61+
image: ghcr.io/octoconsulting/keip/route-webhook:0.10.0
5462
ports:
5563
- containerPort: 7080
5664
name: webhook-http

‎operator/webhook/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION ?= 0.9.0
1+
VERSION ?= 0.10.0
22
HOST_PORT ?= 7080
33
GIT_TAG := webhook_v$(VERSION)
44

‎operator/webhook/introute/sync.py

+73-6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,29 @@
1313

1414
KEYSTORE_PATH = "/etc/keystore"
1515

16+
HTTPS_PORT = 8443
17+
18+
HTTP_PORT = 8080
19+
20+
ACTUATOR_CONFIG_BLOCK = {
21+
"management": {
22+
"endpoint": {
23+
"health": {
24+
"enabled": True
25+
},
26+
"prometheus": {
27+
"enabled": True
28+
}
29+
},
30+
"endpoints": {
31+
"web": {
32+
"exposure": {
33+
"include": "health,prometheus"
34+
}
35+
}
36+
}
37+
}
38+
}
1639

1740
class VolumeConfig:
1841
"""
@@ -29,6 +52,7 @@ class VolumeConfig:
2952
- replicas
3053
- persistentVolumeClaims
3154
- tls
55+
- services
3256
"""
3357

3458
_route_vol_name = "integration-route-config"
@@ -195,10 +219,9 @@ def _get_server_ssl_config(parent) -> Optional[Mapping]:
195219
"key-store": str(PurePosixPath(KEYSTORE_PATH, keystore["key"])),
196220
"key-store-type": keystore["type"].upper(),
197221
},
198-
"port": 8443,
222+
"port": HTTPS_PORT,
199223
}
200224

201-
202225
def _service_name_env_var(parent) -> Mapping[str, str]:
203226
return {"name": "SERVICE_NAME", "value": parent["metadata"]["name"]}
204227

@@ -218,6 +241,8 @@ def _spring_app_config_env_var(parent) -> Optional[Mapping]:
218241
app_config["spring"]["config.import"] = "kubernetes:"
219242
app_config["spring"]["cloud"] = cloud_config
220243

244+
app_config.update(ACTUATOR_CONFIG_BLOCK)
245+
221246
return {
222247
"name": "SPRING_APPLICATION_JSON",
223248
"value": json.dumps(app_config),
@@ -279,10 +304,10 @@ def _create_pod_template(parent, labels, integration_image) -> Mapping[str, Any
279304

280305
vol_config = VolumeConfig(parent["spec"])
281306

282-
has_tls = "tls" in parent["spec"] and "keystore" in parent["spec"]["tls"]
307+
has_tls = _has_tls(parent)
283308

284-
scheme = "HTTPS" if has_tls else "HTTP"
285-
management_port = 8443 if has_tls else 8080
309+
scheme = _get_scheme(has_tls).upper()
310+
management_port = _get_management_port(has_tls)
286311

287312
pod_template = {
288313
"metadata": {"labels": labels},
@@ -388,9 +413,51 @@ def _new_deployment(parent):
388413

389414
return deployment
390415

416+
def _new_actuator_service(parent):
417+
parent_metadata = parent["metadata"]
418+
419+
has_tls = _has_tls(parent)
420+
scheme = _get_scheme(has_tls)
421+
management_port = _get_management_port(has_tls)
422+
423+
service = {
424+
"apiVersion": "v1",
425+
"kind": "Service",
426+
"metadata": {
427+
"labels": {
428+
"integration-route": parent_metadata["name"],
429+
"prometheus-metrics-enabled": "true"
430+
},
431+
"name": f'{parent_metadata["name"]}-actuator'
432+
},
433+
"spec": {
434+
"ports": [
435+
{
436+
"name": scheme,
437+
"port": management_port,
438+
"protocol": "TCP",
439+
"targetPort": management_port
440+
}
441+
],
442+
"selector": {
443+
"app.kubernetes.io/instance": f'integrationroute-{parent_metadata["name"]}'
444+
}
445+
}
446+
}
447+
448+
return service
449+
450+
def _has_tls(parent) -> bool:
451+
return "tls" in parent["spec"] and "keystore" in parent["spec"]["tls"]
452+
453+
def _get_scheme(has_tls) -> str:
454+
return "https" if has_tls else "http"
455+
456+
def _get_management_port(has_tls) -> int:
457+
return HTTPS_PORT if has_tls else HTTP_PORT
391458

392459
def _gen_children(parent) -> List[Mapping]:
393-
return [_new_deployment(parent)]
460+
return [_new_deployment(parent), _new_actuator_service(parent)]
394461

395462

396463
def sync(parent) -> Mapping:

‎operator/webhook/test/json/full-response.json

+25-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
"env": [
107107
{
108108
"name": "SPRING_APPLICATION_JSON",
109-
"value": "{\"spring\": {\"application\": {\"name\": \"testroute\"}, \"config.import\": \"kubernetes:\", \"cloud\": {\"kubernetes\": {\"config\": {\"fail-fast\": true, \"namespace\": \"testspace\", \"sources\": [{\"name\": \"testroute-props\"}, {\"labels\": {\"group\": \"ir-common\"}}]}, \"secrets\": {\"paths\": \"/etc/secrets\"}}}}, \"server\": {\"ssl\": {\"key-alias\": \"certificate\", \"key-store\": \"/etc/keystore/test-keystore.jks\", \"key-store-type\": \"JKS\"}, \"port\": 8443}}"
109+
"value": "{\"spring\": {\"application\": {\"name\": \"testroute\"}, \"config.import\": \"kubernetes:\", \"cloud\": {\"kubernetes\": {\"config\": {\"fail-fast\": true, \"namespace\": \"testspace\", \"sources\": [{\"name\": \"testroute-props\"}, {\"labels\": {\"group\": \"ir-common\"}}]}, \"secrets\": {\"paths\": \"/etc/secrets\"}}}}, \"server\": {\"ssl\": {\"key-alias\": \"certificate\", \"key-store\": \"/etc/keystore/test-keystore.jks\", \"key-store-type\": \"JKS\"}, \"port\": 8443}, \"management\": {\"endpoint\": {\"health\": {\"enabled\": true}, \"prometheus\": {\"enabled\": true}}, \"endpoints\": {\"web\": {\"exposure\": {\"include\": \"health,prometheus\"}}}}}"
110110
},
111111
{
112112
"name": "JDK_JAVA_OPTIONS",
@@ -216,6 +216,30 @@
216216
}
217217
}
218218
}
219+
},
220+
{
221+
"apiVersion": "v1",
222+
"kind": "Service",
223+
"metadata": {
224+
"labels": {
225+
"integration-route": "testroute",
226+
"prometheus-metrics-enabled": "true"
227+
},
228+
"name": "testroute-actuator"
229+
},
230+
"spec": {
231+
"ports": [
232+
{
233+
"name": "https",
234+
"port": 8443,
235+
"protocol": "TCP",
236+
"targetPort": 8443
237+
}
238+
],
239+
"selector": {
240+
"app.kubernetes.io/instance": "integrationroute-testroute"
241+
}
242+
}
219243
}
220244
]
221245
}

‎operator/webhook/test/test_sync.py

+30-11
Original file line numberDiff line numberDiff line change
@@ -69,25 +69,44 @@ def test_spring_app_config_json_missing_props_and_secret_sources(full_route):
6969
del full_route["spec"]["secretSources"]
7070

7171
spring_conf = _spring_app_config_env_var(full_route)
72-
json_props = json.loads(spring_conf["value"])
72+
actual_json = spring_conf["value"]
7373

7474
assert spring_conf["name"] == "SPRING_APPLICATION_JSON"
7575

76-
expected_json = {
77-
"spring": {"application": {"name": "testroute"}},
76+
expected_json = json.dumps({
77+
"spring": {
78+
"application": {
79+
"name": "testroute"
80+
}
81+
},
7882
"server": {
7983
"ssl": {
8084
"key-alias": "certificate",
81-
"key-store": str(
82-
PurePosixPath("/", "etc", "keystore", "test-keystore.jks")
83-
),
84-
"key-store-type": "JKS",
85+
"key-store": "/etc/keystore/test-keystore.jks",
86+
"key-store-type": "JKS"
8587
},
86-
"port": 8443,
88+
"port": 8443
8789
},
88-
}
89-
90-
assert json_props == expected_json
90+
"management": {
91+
"endpoint": {
92+
"health": {
93+
"enabled": True
94+
},
95+
"prometheus": {
96+
"enabled": True
97+
}
98+
},
99+
"endpoints": {
100+
"web": {
101+
"exposure": {
102+
"include": "health,prometheus"
103+
}
104+
}
105+
}
106+
}
107+
})
108+
109+
assert actual_json == expected_json
91110

92111

93112
def test_pod_template_no_annotations(full_route):

0 commit comments

Comments
 (0)
Please sign in to comment.