Skip to content

Commit 502f69e

Browse files
authored
Add possibility to configure mTLS validityDays and renewalDays for each KafkaUser (#12658)
Signed-off-by: Lukas Kral <lukywill16@gmail.com>
1 parent 34a1c9a commit 502f69e

23 files changed

Lines changed: 372 additions & 31 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* Add `UseBackgroundPodDeletion` feature gate (alpha, disabled by default) to use background deletion propagation when deleting pods during rolling updates.
1313
* Strimzi Drain Cleaner updated to 1.6.0 (included in the Strimzi installation files)
1414
* Strimzi Access Operator updated to 0.3.0 - included in Strimzi installation files, examples, and documentation
15+
* It's now possible to configure mTLS `validityDays` and `renewalDays` for each `KafkaUser`
1516

1617
### Major changes, deprecations, and removals
1718

api/src/main/java/io/strimzi/api/kafka/model/user/KafkaUserAuthentication.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,28 @@
88
import com.fasterxml.jackson.annotation.JsonSubTypes;
99
import com.fasterxml.jackson.annotation.JsonTypeInfo;
1010
import io.strimzi.api.kafka.model.common.UnknownPropertyPreserving;
11+
import io.strimzi.crdgenerator.annotations.CelValidation;
1112
import io.strimzi.crdgenerator.annotations.Description;
1213
import lombok.EqualsAndHashCode;
1314
import lombok.ToString;
1415

1516
import java.util.HashMap;
1617
import java.util.Map;
1718

19+
@CelValidation(rules = {
20+
@CelValidation.CelValidationRule(
21+
rule = "self.type == 'tls' || (!has(self.validityDays) && !has(self.renewalDays))",
22+
message = "'validityDays' and 'renewalDays' can be configured only with 'type: tls'"
23+
),
24+
@CelValidation.CelValidationRule(
25+
rule = "self.type != 'tls' || (has(self.renewalDays) == has(self.validityDays))",
26+
message = "Both 'validityDays' and 'renewalDays' must be set together, or both must be unset."
27+
),
28+
@CelValidation.CelValidationRule(
29+
rule = "self.type != 'tls' || !has(self.renewalDays) || !has(self.validityDays) || self.renewalDays < self.validityDays",
30+
message = "'renewalDays' must be less than 'validityDays'."
31+
)
32+
})
1833
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
1934
include = JsonTypeInfo.As.EXISTING_PROPERTY,
2035
property = "type")

api/src/main/java/io/strimzi/api/kafka/model/user/KafkaUserTlsClientAuthentication.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
99
import io.strimzi.api.kafka.model.common.Constants;
1010
import io.strimzi.crdgenerator.annotations.Description;
11+
import io.strimzi.crdgenerator.annotations.Minimum;
1112
import io.sundr.builder.annotations.Buildable;
1213
import lombok.EqualsAndHashCode;
1314
import lombok.ToString;
@@ -17,18 +18,52 @@
1718
builderPackage = Constants.FABRIC8_KUBERNETES_API
1819
)
1920
@JsonInclude(JsonInclude.Include.NON_NULL)
20-
@JsonPropertyOrder({"type"})
21+
@JsonPropertyOrder({"type", "validityDays", "renewalDays"})
2122
@EqualsAndHashCode(callSuper = true)
2223
@ToString(callSuper = true)
2324
public class KafkaUserTlsClientAuthentication extends KafkaUserAuthentication {
2425
public static final String TYPE_TLS = "tls";
2526

27+
private Integer validityDays;
28+
private Integer renewalDays;
29+
2630
@Description("Must be `" + TYPE_TLS + "`")
2731
@JsonInclude(JsonInclude.Include.NON_NULL)
2832
@Override
2933
public String getType() {
3034
return TYPE_TLS;
3135
}
3236

37+
@Description(
38+
"Number of days for which the user certificate is valid. " +
39+
"Both this property and `renewalDays` must be configured together." +
40+
"The value must be greater than 0 and greater than `renewalDays`." +
41+
"If not configured, the Clients CA configuration is used."
42+
)
43+
@Minimum(1)
44+
@JsonInclude(value = JsonInclude.Include.NON_NULL)
45+
public Integer getValidityDays() {
46+
return this.validityDays;
47+
}
48+
49+
public void setValidityDays(Integer validityDays) {
50+
this.validityDays = validityDays;
51+
}
52+
53+
@Description(
54+
"Number of days before certificate expiration when the user certificate is renewed. " +
55+
"Both this property and `validityDays` must be configured together." +
56+
"The value must be greater than 0 and less than `validityDays`." +
57+
"If not configured, the Clients CA configuration is used."
58+
)
59+
@Minimum(1)
60+
@JsonInclude(value = JsonInclude.Include.NON_NULL)
61+
public Integer getRenewalDays() {
62+
return renewalDays;
63+
}
64+
65+
public void setRenewalDays(Integer renewalDays) {
66+
this.renewalDays = renewalDays;
67+
}
3368

3469
}

api/src/test/java/io/strimzi/api/kafka/model/CelValidationIT.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import io.strimzi.api.kafka.model.connect.KafkaConnect;
1414
import io.strimzi.api.kafka.model.kafka.Kafka;
1515
import io.strimzi.api.kafka.model.mirrormaker2.KafkaMirrorMaker2;
16+
import io.strimzi.api.kafka.model.user.KafkaUser;
1617
import io.strimzi.test.CrdUtils;
1718
import io.strimzi.test.ReadWriteUtils;
1819
import io.strimzi.test.TestUtils;
@@ -61,6 +62,10 @@ static Stream<Arguments> celRules() {
6162
final String valueFromRequired = "valueFrom property is required";
6263
final String ccStrimziTypeNotSupported = "value type not supported";
6364

65+
final String validityRenewalDaysSetTogether = "Both 'validityDays' and 'renewalDays' must be set together, or both must be unset.";
66+
final String renewalMustBeLessThanValidity = "'renewalDays' must be less than 'validityDays'.";
67+
final String validityRenewalMustBeSetUnderTls = "'validityDays' and 'renewalDays' can be configured only with 'type: tls'";
68+
6469
return Stream.of(
6570
Arguments.of(Kafka.class, "Kafka-cel-rack-topology-label-missing-key.yaml", topologyKeyRequired),
6671
Arguments.of(Kafka.class, "Kafka-cel-rack-environment-variable-missing-name.yaml", envVarNameRequired),
@@ -78,7 +83,12 @@ static Stream<Arguments> celRules() {
7883

7984
Arguments.of(KafkaMirrorMaker2.class, "KafkaMirrorMaker2-cel-rack-topology-label-missing-key.yaml", topologyKeyRequired),
8085
Arguments.of(KafkaMirrorMaker2.class, "KafkaMirrorMaker2-cel-rack-environment-variable-missing-name.yaml", envVarNameRequired),
81-
Arguments.of(KafkaMirrorMaker2.class, "KafkaMirrorMaker2-cel-metrics-jmx-missing-valueFrom.yaml", valueFromRequired)
86+
Arguments.of(KafkaMirrorMaker2.class, "KafkaMirrorMaker2-cel-metrics-jmx-missing-valueFrom.yaml", valueFromRequired),
87+
88+
Arguments.of(KafkaUser.class, "KafkaUser-cel-missing-renewal-days.yaml", validityRenewalDaysSetTogether),
89+
Arguments.of(KafkaUser.class, "KafkaUser-cel-missing-validity-days.yaml", validityRenewalDaysSetTogether),
90+
Arguments.of(KafkaUser.class, "KafkaUser-cel-renewal-higher-than-validity.yaml", renewalMustBeLessThanValidity),
91+
Arguments.of(KafkaUser.class, "KafkaUser-cel-validity-renewal-configured-outside-tls.yaml", validityRenewalMustBeSetUnderTls)
8292
);
8393
}
8494

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
apiVersion: "kafka.strimzi.io/v1"
3+
kind: "KafkaUser"
4+
metadata:
5+
name: my-user
6+
spec:
7+
authentication:
8+
type: tls
9+
validityDays: 10
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
apiVersion: "kafka.strimzi.io/v1"
3+
kind: "KafkaUser"
4+
metadata:
5+
name: my-user
6+
spec:
7+
authentication:
8+
type: tls
9+
renewalDays: 10
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
apiVersion: "kafka.strimzi.io/v1"
3+
kind: "KafkaUser"
4+
metadata:
5+
name: my-user
6+
spec:
7+
authentication:
8+
type: tls
9+
renewalDays: 10
10+
validityDays: 9
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
apiVersion: "kafka.strimzi.io/v1"
3+
kind: "KafkaUser"
4+
metadata:
5+
name: my-user
6+
spec:
7+
authentication:
8+
type: scram-sha-512
9+
renewalDays: 10
10+
validityDays: 20

development-docs/systemtests/io.strimzi.systemtest.operators.user.UserST.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,28 @@
9797
* [user-operator](labels/user-operator.md)
9898

9999

100+
## testTlsValidityDays
101+
102+
**Description:** Verifies functionality of the mTLS `validityDays` and `renewalDays` configured inside each KafkaUser.
103+
104+
**Steps:**
105+
106+
| Step | Action | Result |
107+
| - | - | - |
108+
| 1. | Create a `KafkaTopic` in the existing Kafka cluster to send and receive messages. | `KafkaTopic` is created. |
109+
| 2. | Create a `KafkaUser` with TLS authentication without configuring `validityDays` and `renewalDays`. The values from the User Operator are used. | `KafkaUser` is created with values from the User Operator. |
110+
| 3. | Obtain the `KafkaUser`'s `Secret` and check the validity period of the user certificate. | The default validity period is 200 days. |
111+
| 4. | Send and receive messages to verify connection to the Kafka cluster using the TLS `KafkaUser`. | Messages are successfully sent and received. |
112+
| 5. | Change the `validityDays` and `renewalDays` in `KafkaUser` `.spec.authentication` to 40 and 20. | The `validityDays` and `renewalDays` are updated in the `KafkaUser`. |
113+
| 6. | The certificate is renewed automatically after the `validityDays` and `renewalDays` values are updated. | The user certificate is renewed. |
114+
| 7. | Obtain the `KafkaUser` `Secret` again and check the validity period of the user certificate. | Validity period is 40 days. |
115+
| 8. | Send and receive messages again to verify connection to the Kafka cluster using the new user certificate. | Messages are successfully sent and received using the new certificate. |
116+
117+
**Labels:**
118+
119+
* [user-operator](labels/user-operator.md)
120+
121+
100122
## testUpdateUser
101123

102124
**Description:** Verifies updating a Kafka user from TLS to SCRAM-SHA-512 authentication and validates user secret contents.

development-docs/systemtests/labels/user-operator.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ They verify user authentication mechanisms (TLS, SCRAM-SHA-512, external TLS), a
1515
- [testTlsExternalUser](../io.strimzi.systemtest.operators.user.UserST.md)
1616
- [testTlsExternalUserWithQuotas](../io.strimzi.systemtest.operators.user.UserST.md)
1717
- [testTlsUserWithQuotas](../io.strimzi.systemtest.operators.user.UserST.md)
18+
- [testTlsValidityDays](../io.strimzi.systemtest.operators.user.UserST.md)
1819
- [testUpdateUser](../io.strimzi.systemtest.operators.user.UserST.md)
1920
- [testUserWithNameMoreThan64Chars](../io.strimzi.systemtest.operators.user.UserST.md)
2021
- [testUserWithQuotas](../io.strimzi.systemtest.operators.user.UserST.md)

0 commit comments

Comments
 (0)