Skip to content

Commit 8fd3d8c

Browse files
committed
implementation
Signed-off-by: Lukas Kral <lukywill16@gmail.com> finish implementation Signed-off-by: Lukas Kral <lukywill16@gmail.com> fix tests Signed-off-by: Lukas Kral <lukywill16@gmail.com> add changelog Signed-off-by: Lukas Kral <lukywill16@gmail.com> same value of validityDays and renewalDays in KafkaUserModelCertificateHandlingTest Signed-off-by: Lukas Kral <lukywill16@gmail.com> crds 🤦 Signed-off-by: Lukas Kral <lukywill16@gmail.com> update API docs and add ST for this change Signed-off-by: Lukas Kral <lukywill16@gmail.com> Signed-off-by: Lukas Kral <lukywill16@gmail.com> fix spotbugs Signed-off-by: Lukas Kral <lukywill16@gmail.com>
1 parent 6f20d3a commit 8fd3d8c

19 files changed

Lines changed: 537 additions & 95 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Add `UseBackgroundPodDeletion` feature gate (alpha, disabled by default) to use background deletion propagation when deleting pods during rolling updates.
77
* Strimzi Drain Cleaner updated to 1.6.0 (included in the Strimzi installation files)
88
* Strimzi Access Operator updated to 0.3.0 - included in Strimzi installation files, examples, and documentation
9+
* Add possibility to configure mTLS `validityDays` and `renewalDays` for each `KafkaUser`
910

1011
### Major changes, deprecations, and removals
1112

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,20 @@
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+
})
1825
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
1926
include = JsonTypeInfo.As.EXISTING_PROPERTY,
2027
property = "type")

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

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.fasterxml.jackson.annotation.JsonInclude;
88
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
99
import io.strimzi.api.kafka.model.common.Constants;
10+
import io.strimzi.crdgenerator.annotations.CelValidation;
1011
import io.strimzi.crdgenerator.annotations.Description;
1112
import io.sundr.builder.annotations.Buildable;
1213
import lombok.EqualsAndHashCode;
@@ -17,18 +18,60 @@
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+
@CelValidation(rules = {
38+
@CelValidation.CelValidationRule(
39+
rule = "self > 0",
40+
message = "'validityDays' has to be higher than 0."
41+
)
42+
})
43+
@Description(
44+
"Number of days for which the user certificate should be valid. " +
45+
"If not configured, default User Operator value is used. " +
46+
"If new validity policy would make the current certificate expired or current certificate's validity period would exceed new policy, " +
47+
"the certificate is immediately renewed, without waiting for maintenance window. "
48+
)
49+
@JsonInclude(value = JsonInclude.Include.NON_NULL)
50+
public Integer getValidityDays() {
51+
return this.validityDays;
52+
}
53+
54+
public void setValidityDays(Integer validityDays) {
55+
this.validityDays = validityDays;
56+
}
57+
58+
@CelValidation(rules = {
59+
@CelValidation.CelValidationRule(
60+
rule = "self > 0",
61+
message = "'renewalDays' has to be higher than 0."
62+
)
63+
})
64+
@Description(
65+
"Configures how many days before the certificate expiration should be the user certificate renewed. " +
66+
"If not configured, default User Operator value is used."
67+
)
68+
@JsonInclude(value = JsonInclude.Include.NON_NULL)
69+
public Integer getRenewalDays() {
70+
return renewalDays;
71+
}
72+
73+
public void setRenewalDays(Integer renewalDays) {
74+
this.renewalDays = renewalDays;
75+
}
3376

3477
}

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 `KafkaTopic` to which we will send (and from which we will receive) messages - created in existing Kafka cluster. | `KafkaTopic` is created. |
109+
| 2. | Create `KafkaUser` with TLS authentication; together with default `validityDays` (200 days) and `renewalDays` (20 days) - configured in User operator. | `KafkaUser` is created with defaults. |
110+
| 3. | Obtain the `KafkaUser`'s `Secret` and check validity period of the user certificate. | Validity period should be default - 200 days. |
111+
| 4. | Do message transmission to verify, that we are able to connect to Kafka cluster with the TLS `KafkaUser`. | Messages are successfully sent and received. |
112+
| 5. | Change the `validityDays` and `renewalDays` in the `KafkaUser` `.spec.authentication` to 60 and 10. | The `validityDays` and `renewalDays` should be changed in the `KafkaUser`. |
113+
| 6. | Because the current certificate would exceed the new validity period, `KafkaUser`'s `Secret` and user certificate should be renewed - we are waiting for the certificate change. | The user certificate was changed. |
114+
| 7. | Obtain the `KafkaUser`'s `Secret` again and check the validity period of the user certificate. | Validity period should be 60 days. |
115+
| 8. | Do message transmission again to verify, that we are able to connect to Kafka cluster with the new user's certificate. | Messages are successfully sent and received using 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)

documentation/modules/appendix_crds.adoc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2678,6 +2678,12 @@ It must have the value `tls` for the type `KafkaUserTlsClientAuthentication`.
26782678
|type
26792679
|string
26802680
|Must be `tls`.
2681+
|validityDays
2682+
|integer
2683+
|Number of days for which the user certificate should be valid. If not configured, default User Operator value is used. If new validity policy would make the current certificate expired or current certificate's validity period would exceed new policy, the certificate is immediately renewed, without waiting for maintenance window.
2684+
|renewalDays
2685+
|integer
2686+
|Configures how many days before the certificate expiration should be the user certificate renewed. If not configured, default User Operator value is used.
26812687
|====
26822688

26832689
[id='type-KafkaUserTlsExternalClientAuthentication-{context}']

operator-common/src/main/java/io/strimzi/operator/common/model/Ca.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,41 @@ public boolean isExpiring(Secret secret, String certKey) {
536536
return certNeedsRenewal(currentCert);
537537
}
538538

539+
/**
540+
* Checks if the validityDays configuration is different from previous state.
541+
* If yes, the method checks if the new configuration of validityDays would make the certificate expired
542+
* or if the current Certificate's validity period exceeds the new policy.
543+
*
544+
* @param secret Secret with the certificate
545+
* @param certKey Key under which is the certificate stored
546+
*
547+
* @return True if the certificate should be renewed due to new validity period. False otherwise.
548+
*/
549+
public boolean requiresImmediateRenewalDueToValidityChange(Secret secret, String certKey) {
550+
X509Certificate currentCert = cert(secret, certKey);
551+
552+
Instant notBefore = currentCert.getNotBefore().toInstant();
553+
Instant notAfter = currentCert.getNotAfter().toInstant();
554+
int currentValidityDays = (int) ChronoUnit.DAYS.between(notBefore, notAfter);
555+
556+
if (currentValidityDays != validityDays) {
557+
Instant wouldExpireUnderNewPolicy = notBefore.plus(validityDays, ChronoUnit.DAYS);
558+
559+
if (!this.clock.instant().isBefore(wouldExpireUnderNewPolicy)) {
560+
LOGGER.infoCr(reconciliation, "Certificate of Secret {}/{} would be expired under new validity policy, it will be renewed",
561+
secret.getMetadata().getNamespace(), secret.getMetadata().getName());
562+
return true;
563+
}
564+
if (currentValidityDays > validityDays) {
565+
LOGGER.infoCr(reconciliation, "Certificate's current validity period of Secret {}/{} exceeds new policy, it will be renewed",
566+
secret.getMetadata().getNamespace(), secret.getMetadata().getName());
567+
return true;
568+
}
569+
}
570+
571+
return false;
572+
}
573+
539574
/**
540575
* Returns whether the certificate is expiring or not
541576
*

operator-common/src/test/java/io/strimzi/operator/common/operator/MockCertManager.java

Lines changed: 25 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
package io.strimzi.operator.common.operator;
66

77
import io.strimzi.certs.CertManager;
8+
import io.strimzi.certs.OpenSslCertManager;
89
import io.strimzi.certs.Subject;
10+
import io.strimzi.operator.common.Util;
911

1012
import java.io.ByteArrayOutputStream;
1113
import java.io.File;
@@ -76,59 +78,9 @@ public class MockCertManager implements CertManager {
7678
D0z+vgrfionoRhyWUDh7POlWwdUOWiBDBOFrkgeKNphSC0glYFN+2IW7
7779
-----END CERTIFICATE-----
7880
""";
79-
private static final String CLIENTS_KEY = """
80-
-----BEGIN PRIVATE KEY-----
81-
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCWws5FEJOpfZ/s
82-
FJWYbYdJVxmZB+5PjCwA2TUZxF/3P4w/5g2KZaXNy89AfBC5vRDRgyDyj/RwcDg8
83-
0kDGKobcGhTx5YkWoNvR/2WuTN6KC8DM78bfEREDHDxiXfAXrMIi7Ux2FvUX13l7
84-
6Sp9kiG3ETLjFom3n/qhg1ITJqPJSJi3tey0o2Pd5Arv0MIhQyep++URtZfND5fg
85-
F5x7hgnSf9Q1P1dJnVadu+ohUmmG7g+zX4rTqjN2jmHcf9V4lLKdPGWwLQEGnP9y
86-
Dqlm8x12M/BcIJasRgcciVsKYFuXe09NEYBvUjW8L6gaQ6U9wcYZ2MlKW/8LMGkS
87-
FfO4quAJAgMBAAECggEAQ1NdsEQV3UQHrfMHV1naZ6so+EktaILNh9d4OjiTLqRH
88-
aqW++EYqhDv3IvIEuh2vrBCmHwygebHzu12dpaGKNjLDlb8OuHc/k4k9jFgxrW5Q
89-
PHT719QUR9JNORSASuJQlC5qzfW0oGAOlYJsAkXHHqzkj7sZ51HfKE+v0HOaAyHj
90-
8gOeBNk1Mtb3Sj5mXpWFQGpXXuG01Vsjj7Nj/91a4KtWAWOqeagc2Bk+C0aZ7d1p
91-
SQcLVWjJYwoejgCc2elZxzbfmDtVSAgFtdTPxwf9uflMducTfp/RyaQbzuYSrSmz
92-
rnZq/59i9lYl314rjjkCusDaDSPdK5QziN54tQ+BcQKBgQDE9ulPecHtZhOsI9zT
93-
J+xTJtZq1w8kFV5jMqXnL3jAFBXsC3s02KLq36ppvf8kVzUHrHE+DiWnHKEIiy/U
94-
luMnPvJb/6qqdQNDpcrF+CE2JevvoPl5hrKdyzAI4TNu96aU+9qVrO2rB7bWBvlA
95-
dVwIZ8zkk3pwbdEj9rYpMA1VVQKBgQDD8rJAEd9fLtX53NQh8XWEJ1dEfncmg/ib
96-
0vyoYlqSDjPTot85sCunVZNHwUoKUsukzi+Tc9hxaXCjEB6ICVeXqWc4PYnbK79H
97-
N+2X6YaO/rKAzbxM1F/Km3IzzvoXFJnPG4hxvBmpdApKgBGOVixnjD7PzNz4jh9u
98-
1qhDocdf5QKBgQCDsLqporTgr0Ez9P5uR+Egb3UpFgVPkOH83R5Dhl/rvQIzQjHs
99-
UXQMKeNcs+XlPFF+gfNtFDRkmSWp+rXOI9xYnyOYE0belUHLdwwudQpvk8c9/pkO
100-
gdrm2bWSGlAzP22nawTo0ihOE+hRDXSVfmI8VHqP0XMpvKL6srd0rmYbyQKBgAYD
101-
PXr/0WXfTwuSviOogB2lA2WDp+5ToF5PtBcKpZLTwr1cwxLHGB/TXWiXQslcTwlo
102-
lkclB+A7BwzJ4tXzy29I8HTmVoOWLRFnYvAFZ26d3CZdqciFv8a8zF1QnZX1uN6F
103-
DsPGrNbpS6OLmH5QoJ4wzICd3a321noVNiaVIUQNAoGAYu4RrGcBKRuy75lfKARD
104-
gNxxVlvuI33ieK/3A9nUWc3LXl5D/yiSePCUs4giOwi2gFrGjcmIqLXZE5XUYGEu
105-
zXWWQCGbMqyX15/A2/eTuj658F292nkSyU/5U2999WjCm79sfnGJB1zavfv2fzGK
106-
g4trXCUkjAVG3Toaq05saGM=
107-
-----END PRIVATE KEY-----
108-
""";
109-
private static final String CLIENTS_CERT = """
110-
-----BEGIN CERTIFICATE-----
111-
MIIDhjCCAm6gAwIBAgIJAOKzFJgrn+rZMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV
112-
BAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQg
113-
Q29tcGFueSBMdGQxEzARBgNVBAMMCmNsaWVudHMtY2EwIBcNMTgwODIzMTYyMTI1
114-
WhgPMjExODA3MzAxNjIxMjVaMFcxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZh
115-
dWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQxEzARBgNVBAMM
116-
CmNsaWVudHMtY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCWws5F
117-
EJOpfZ/sFJWYbYdJVxmZB+5PjCwA2TUZxF/3P4w/5g2KZaXNy89AfBC5vRDRgyDy
118-
j/RwcDg80kDGKobcGhTx5YkWoNvR/2WuTN6KC8DM78bfEREDHDxiXfAXrMIi7Ux2
119-
FvUX13l76Sp9kiG3ETLjFom3n/qhg1ITJqPJSJi3tey0o2Pd5Arv0MIhQyep++UR
120-
tZfND5fgF5x7hgnSf9Q1P1dJnVadu+ohUmmG7g+zX4rTqjN2jmHcf9V4lLKdPGWw
121-
LQEGnP9yDqlm8x12M/BcIJasRgcciVsKYFuXe09NEYBvUjW8L6gaQ6U9wcYZ2MlK
122-
W/8LMGkSFfO4quAJAgMBAAGjUzBRMB0GA1UdDgQWBBQUwNmfsNj+PM240pVPxYx9
123-
Q9eQhDAfBgNVHSMEGDAWgBQUwNmfsNj+PM240pVPxYx9Q9eQhDAPBgNVHRMBAf8E
124-
BTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAnhbNKwMmnayHsT6kKgyyDV6RUUYs6
125-
nYf3nx+GIQWSw4c5TOHDcTWdKpOxVnLNXYKQoSkb1RBoSMLBdQwidZ5K2DB5eXaG
126-
rcfEbKNBc5ZCFgFEAyy35pitJOmU/KzCdKyvx+TR5hIgGoKajYX5JZxj+1rTPGKO
127-
ePT9iFp1ZbzHjgw6vFeJ+D2ov6HfW6C/KuK9Y6xUpvRQLVjMJYCyzxkxQAxZvu/0
128-
0HVYYH6UJ7kuWywFMWoBdZ8US/vuUSBYyCGNL9p6ol+h9rsz3cIWBVBjx8C3qKki
129-
QtlIdmFljGSaGGY6aJjUvUdgoPp1yQPa5oS+afr5g9gaEp4lxP6mc+Li
130-
-----END CERTIFICATE-----
131-
""";
81+
82+
private static final String CLIENTS_KEY;
83+
private static final String CLIENTS_CERT;
13284

13385
private static final String ALTERNATE_CLIENTS_CERT = """
13486
-----BEGIN CERTIFICATE-----
@@ -269,6 +221,24 @@ public class MockCertManager implements CertManager {
269221
CLUSTER_CERT_STORE = loadResource(is);
270222
is = MockCertManager.class.getClassLoader().getResourceAsStream("CLIENTS_CERT.str");
271223
CLIENTS_CERT_STORE = loadResource(is);
224+
// generate clients certificate and key, to satisfy the validity days check mainly in KafkaUser tests
225+
OpenSslCertManager openSslCertManager = new OpenSslCertManager();
226+
try {
227+
File keyFile = Files.createTempFile("tls", "key").toFile();
228+
File csrFile = Files.createTempFile("tls", "csr").toFile();
229+
File certFile = Files.createTempFile("tls", "cert").toFile();
230+
231+
Subject.Builder subject = new Subject.Builder();
232+
subject.withCommonName("strimzi-client");
233+
234+
openSslCertManager.generateCsr(keyFile, csrFile, subject.build());
235+
openSslCertManager.generateCert(csrFile, Util.decodeBytesFromBase64(clusterCaKey()), Util.decodeBytesFromBase64(clusterCaCert()), certFile, subject.build(), 365);
236+
237+
CLIENTS_CERT = Base64.getEncoder().encodeToString(Files.readAllBytes(certFile.toPath()));
238+
CLIENTS_KEY = Base64.getEncoder().encodeToString(Files.readAllBytes(keyFile.toPath()));
239+
} catch (Exception e) {
240+
throw new RuntimeException("Failed to create tmp files");
241+
}
272242
}
273243

274244
public static String clusterCaCert() {
@@ -280,29 +250,21 @@ public static String clusterCaKey() {
280250
}
281251

282252
public static String clientsCaCert() {
283-
return Base64.getEncoder().encodeToString(CLIENTS_CERT.getBytes(Charset.defaultCharset()));
253+
return CLIENTS_CERT;
284254
}
285255

286256
public static String alternateClientsCaCert() {
287257
return Base64.getEncoder().encodeToString(ALTERNATE_CLIENTS_CERT.getBytes(Charset.defaultCharset()));
288258
}
289259

290260
public static String clientsCaKey() {
291-
return Base64.getEncoder().encodeToString(CLIENTS_KEY.getBytes(Charset.defaultCharset()));
261+
return CLIENTS_KEY;
292262
}
293263

294264
public static String clusterCaCertStore() {
295265
return Base64.getEncoder().encodeToString(CLUSTER_CERT_STORE);
296266
}
297267

298-
public static String clientsCaCertStore() {
299-
return Base64.getEncoder().encodeToString(CLIENTS_CERT_STORE);
300-
}
301-
302-
public static String certStorePassword() {
303-
return Base64.getEncoder().encodeToString(CERT_STORE_PASSWORD.getBytes(Charset.defaultCharset()));
304-
}
305-
306268
private void write(File keyFile, String str) throws IOException {
307269
try (FileWriter writer = new FileWriter(keyFile)) {
308270
writer.write(str);

packaging/helm-charts/helm3/strimzi-kafka-operator/crds/044-Crd-kafkauser.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,31 @@ spec:
8181
required:
8282
- valueFrom
8383
description: "Specify the password for the user. If not set, a new password is generated by the User Operator."
84+
renewalDays:
85+
type: integer
86+
description: "Configures how many days before the certificate expiration should be the user certificate renewed. If not configured, default User Operator value is used."
87+
x-kubernetes-validations:
88+
- rule: self > 0
89+
message: '''renewalDays'' has to be higher than 0.'
8490
type:
8591
type: string
8692
enum:
8793
- tls
8894
- tls-external
8995
- scram-sha-512
9096
description: Authentication type.
97+
validityDays:
98+
type: integer
99+
description: "Number of days for which the user certificate should be valid. If not configured, default User Operator value is used. If new validity policy would make the current certificate expired or current certificate's validity period would exceed new policy, the certificate is immediately renewed, without waiting for maintenance window. "
100+
x-kubernetes-validations:
101+
- rule: self > 0
102+
message: '''validityDays'' has to be higher than 0.'
91103
required:
92104
- type
93105
description: "Authentication mechanism enabled for this Kafka user. The supported authentication mechanisms are `scram-sha-512`, `tls`, and `tls-external`. \n\n* `scram-sha-512` generates a secret with SASL SCRAM-SHA-512 credentials.\n* `tls` generates a secret with user certificate for mutual TLS authentication.\n* `tls-external` does not generate a user certificate. But prepares the user for using mutual TLS authentication using a user certificate generated outside the User Operator.\n ACLs and quotas set for this user are configured in the `CN=<username>` format.\n\nAuthentication is optional. If authentication is not configured, no credentials are generated. ACLs and quotas set for the user are configured in the `<username>` format suitable for SASL authentication."
106+
x-kubernetes-validations:
107+
- rule: self.type == 'tls' || (!has(self.validityDays) && !has(self.renewalDays))
108+
message: "'validityDays' and 'renewalDays' can be configured only with 'type: tls'"
94109
authorization:
95110
type: object
96111
properties:

0 commit comments

Comments
 (0)