Skip to content

Commit 4a155a2

Browse files
Copilotphrocker
andauthored
Add pod-scoped property overrides for ConfigurationOption (#165)
* Initial plan * Add pod-based property override support to ConfigurationOption Co-authored-by: phrocker <[email protected]> * Update pod name configuration to use explicit sentrius.pod.name property Co-authored-by: phrocker <[email protected]> * Add Flyway migration V36 for pod_name column on configuration_options Co-authored-by: phrocker <[email protected]> * Add clarifying comments to Flyway migration V36 Co-authored-by: phrocker <[email protected]> --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: phrocker <[email protected]>
1 parent 2d0de12 commit 4a155a2

File tree

9 files changed

+604
-70
lines changed

9 files changed

+604
-70
lines changed

api/src/main/java/io/sentrius/sso/controllers/api/PropertyOverrideController.java

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.sentrius.sso.core.annotations.LimitAccess;
44
import io.sentrius.sso.core.config.SystemOptions;
55
import io.sentrius.sso.core.controllers.BaseController;
6+
import io.sentrius.sso.core.model.ConfigurationOption;
67
import io.sentrius.sso.core.model.security.enums.ApplicationAccessEnum;
78
import io.sentrius.sso.core.services.ErrorOutputService;
89
import io.sentrius.sso.core.services.PropertyOverrideService;
@@ -12,11 +13,13 @@
1213
import org.springframework.web.bind.annotation.*;
1314

1415
import java.util.HashMap;
16+
import java.util.List;
1517
import java.util.Map;
1618

1719
/**
1820
* REST API controller for managing application property overrides.
1921
* Provides endpoints to view, update, and delete property overrides stored in the database.
22+
* Supports pod-specific and global property overrides.
2023
*/
2124
@Slf4j
2225
@RestController
@@ -36,28 +39,49 @@ public PropertyOverrideController(
3639

3740
/**
3841
* Get all properties with their current values and override status.
42+
* Optionally filter by pod name.
3943
*
44+
* @param podName The pod name to filter by, or null for global properties
4045
* @return Map of property names to property information
4146
*/
4247
@GetMapping
4348
@LimitAccess(applicationAccess = {ApplicationAccessEnum.CAN_MANAGE_APPLICATION})
44-
public ResponseEntity<Map<String, PropertyOverrideService.PropertyInfo>> getAllProperties() {
45-
log.info("Fetching all properties");
46-
Map<String, PropertyOverrideService.PropertyInfo> properties = propertyOverrideService.getAllProperties();
49+
public ResponseEntity<Map<String, PropertyOverrideService.PropertyInfo>> getAllProperties(
50+
@RequestParam(required = false) String podName) {
51+
log.info("Fetching all properties for pod: {}", podName != null ? podName : "global");
52+
Map<String, PropertyOverrideService.PropertyInfo> properties = propertyOverrideService.getAllProperties(podName);
4753
return ResponseEntity.ok(properties);
4854
}
4955

56+
/**
57+
* Get all configuration options for a specific pod.
58+
*
59+
* @param podName The pod name
60+
* @return List of configuration options for the pod
61+
*/
62+
@GetMapping("/pod/{podName}")
63+
@LimitAccess(applicationAccess = {ApplicationAccessEnum.CAN_MANAGE_APPLICATION})
64+
public ResponseEntity<List<ConfigurationOption>> getPropertiesForPod(@PathVariable String podName) {
65+
log.info("Fetching all configurations for pod: {}", podName);
66+
List<ConfigurationOption> configs = propertyOverrideService.getAllConfigurationsForPod(podName);
67+
return ResponseEntity.ok(configs);
68+
}
69+
5070
/**
5171
* Get a specific property value.
72+
* Optionally specify a pod name to get pod-specific override.
5273
*
5374
* @param propertyName The property name
75+
* @param podName The pod name, or null for global lookup
5476
* @return The property value
5577
*/
5678
@GetMapping("/{propertyName}")
5779
@LimitAccess(applicationAccess = {ApplicationAccessEnum.CAN_MANAGE_APPLICATION})
58-
public ResponseEntity<Map<String, String>> getProperty(@PathVariable String propertyName) {
59-
log.info("Fetching property: {}", propertyName);
60-
String value = propertyOverrideService.getProperty(propertyName);
80+
public ResponseEntity<Map<String, String>> getProperty(
81+
@PathVariable String propertyName,
82+
@RequestParam(required = false) String podName) {
83+
log.info("Fetching property: {} for pod: {}", propertyName, podName != null ? podName : "global");
84+
String value = propertyOverrideService.getProperty(podName, propertyName);
6185

6286
if (value == null) {
6387
return ResponseEntity.notFound().build();
@@ -66,26 +90,38 @@ public ResponseEntity<Map<String, String>> getProperty(@PathVariable String prop
6690
Map<String, String> response = new HashMap<>();
6791
response.put("propertyName", propertyName);
6892
response.put("value", value);
93+
if (podName != null) {
94+
response.put("podName", podName);
95+
}
6996
return ResponseEntity.ok(response);
7097
}
7198

7299
/**
73100
* Set or update a property override.
101+
* Optionally specify a pod name for pod-specific override.
74102
*
75-
* @param request The request containing property name and value
103+
* @param request The request containing property name, value, and optional pod name
76104
* @return Success message
77105
*/
78106
@PostMapping
79107
@LimitAccess(applicationAccess = {ApplicationAccessEnum.CAN_MANAGE_APPLICATION})
80108
public ResponseEntity<Map<String, String>> setPropertyOverride(@RequestBody PropertyUpdateRequest request) {
81-
log.info("Setting property override: {} = {}", request.getPropertyName(), request.getValue());
109+
log.info("Setting property override: {} = {} for pod: {}",
110+
request.getPropertyName(), request.getValue(),
111+
request.getPodName() != null ? request.getPodName() : "global");
82112

83113
try {
84-
propertyOverrideService.setPropertyOverride(request.getPropertyName(), request.getValue());
114+
propertyOverrideService.setPropertyOverride(
115+
request.getPodName(),
116+
request.getPropertyName(),
117+
request.getValue());
85118

86119
Map<String, String> response = new HashMap<>();
87120
response.put("message", "Property override saved successfully");
88121
response.put("propertyName", request.getPropertyName());
122+
if (request.getPodName() != null) {
123+
response.put("podName", request.getPodName());
124+
}
89125
return ResponseEntity.ok(response);
90126
} catch (SecurityException e) {
91127
log.warn("Security violation: {}", e.getMessage());
@@ -98,21 +134,28 @@ public ResponseEntity<Map<String, String>> setPropertyOverride(@RequestBody Prop
98134

99135
/**
100136
* Delete a property override (reverts to file value).
137+
* Optionally specify a pod name to delete pod-specific override.
101138
*
102139
* @param propertyName The property name
140+
* @param podName The pod name, or null for global override
103141
* @return Success message
104142
*/
105143
@DeleteMapping("/{propertyName}")
106144
@LimitAccess(applicationAccess = {ApplicationAccessEnum.CAN_MANAGE_APPLICATION})
107-
public ResponseEntity<Map<String, String>> deletePropertyOverride(@PathVariable String propertyName) {
108-
log.info("Deleting property override: {}", propertyName);
145+
public ResponseEntity<Map<String, String>> deletePropertyOverride(
146+
@PathVariable String propertyName,
147+
@RequestParam(required = false) String podName) {
148+
log.info("Deleting property override: {} for pod: {}", propertyName, podName != null ? podName : "global");
109149

110150
try {
111-
propertyOverrideService.removePropertyOverride(propertyName);
151+
propertyOverrideService.removePropertyOverride(podName, propertyName);
112152

113153
Map<String, String> response = new HashMap<>();
114154
response.put("message", "Property override removed successfully");
115155
response.put("propertyName", propertyName);
156+
if (podName != null) {
157+
response.put("podName", podName);
158+
}
116159
return ResponseEntity.ok(response);
117160
} catch (SecurityException e) {
118161
log.warn("Security violation: {}", e.getMessage());
@@ -133,5 +176,11 @@ public ResponseEntity<Map<String, String>> deletePropertyOverride(@PathVariable
133176
public static class PropertyUpdateRequest {
134177
private String propertyName;
135178
private String value;
179+
private String podName;
180+
181+
public PropertyUpdateRequest(String propertyName, String value) {
182+
this.propertyName = propertyName;
183+
this.value = value;
184+
}
136185
}
137186
}
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
create table if not exists "configuration_options" (
22
id BIGSERIAL PRIMARY KEY,
3+
"pod_name" character varying(255),
34
"configuration_name" character varying(250) NOT NULL,
45
"configuration_value" text NOT NULL
5-
);
6+
);
7+
8+
CREATE INDEX IF NOT EXISTS idx_config_pod_name ON configuration_options (pod_name, configuration_name);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-- Add pod_name column to configuration_options for pod-specific overrides
2+
-- NULL pod_name represents global configuration options that apply to all pods
3+
-- Pod-specific overrides take precedence over global overrides when queried
4+
ALTER TABLE configuration_options ADD COLUMN IF NOT EXISTS pod_name VARCHAR(255);
5+
6+
-- Create composite index for efficient pod-based queries (pod_name, configuration_name)
7+
-- Queries filtering by pod_name will use this index
8+
-- Note: If you need to query by configuration_name alone frequently, consider adding a separate index
9+
CREATE INDEX IF NOT EXISTS idx_config_pod_name ON configuration_options (pod_name, configuration_name);

0 commit comments

Comments
 (0)