Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions docs/api-references/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -17840,6 +17840,21 @@ string
</tr>
<tr>
<td>
<code>tidbAuth</code></br>
<em>
<a href="#ticitidbauth">
TiCITiDBAuth
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>TiDBAuth configures the TiDB auth used by TiCI meta.
If it is set, passwordSecret must reference the Secret key that stores the TiDB auth data.</p>
</td>
</tr>
<tr>
<td>
<code>storageClassName</code></br>
<em>
string
Expand Down Expand Up @@ -18250,6 +18265,50 @@ string
</tr>
</tbody>
</table>
<h3 id="ticitidbauth">TiCITiDBAuth</h3>
<p>
(<em>Appears on:</em>
<a href="#ticimetaspec">TiCIMetaSpec</a>)
</p>
<p>
<p>TiCITiDBAuth contains TiDB auth settings used by TiCI.</p>
</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>user</code></br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>User is the TiDB user used by TiCI meta. Defaults to root.</p>
</td>
</tr>
<tr>
<td>
<code>passwordSecret</code></br>
<em>
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#secretkeyselector-v1-core">
Kubernetes core/v1.SecretKeySelector
</a>
</em>
</td>
<td>
<p>PasswordSecret selects the Secret key that stores the TiDB auth data.
The referenced Secret key is required; optional must not be true.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="ticiworkerspec">TiCIWorkerSpec</h3>
<p>
(<em>Appears on:</em>
Expand Down
23 changes: 23 additions & 0 deletions manifests/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43457,6 +43457,29 @@ spec:
terminationGracePeriodSeconds:
format: int64
type: integer
tidbAuth:
properties:
passwordSecret:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
x-kubernetes-validations:
- message: optional must be false because TiCI meta TiDB
auth Secret is required
rule: '!has(self.optional) || self.optional == false'
user:
type: string
required:
- passwordSecret
type: object
tolerations:
items:
properties:
Expand Down
23 changes: 23 additions & 0 deletions manifests/crd/v1/pingcap.com_tidbclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17801,6 +17801,29 @@ spec:
terminationGracePeriodSeconds:
format: int64
type: integer
tidbAuth:
properties:
passwordSecret:
properties:
key:
type: string
name:
type: string
optional:
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
x-kubernetes-validations:
- message: optional must be false because TiCI meta TiDB
auth Secret is required
rule: '!has(self.optional) || self.optional == false'
user:
type: string
required:
- passwordSecret
type: object
tolerations:
items:
properties:
Expand Down
38 changes: 37 additions & 1 deletion pkg/apis/pingcap/v1alpha1/openapi_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions pkg/apis/pingcap/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,11 @@ type TiCIMetaSpec struct {
// +optional
Config string `json:"config,omitempty"`

// TiDBAuth configures the TiDB auth used by TiCI meta.
// If it is set, passwordSecret must reference the Secret key that stores the TiDB auth data.
// +optional
TiDBAuth *TiCITiDBAuth `json:"tidbAuth,omitempty"`

// The storageClassName of the persistent volume for TiCI meta data storage.
// Defaults to Kubernetes default storage class.
// +optional
Expand All @@ -1011,6 +1016,20 @@ type TiCIMetaSpec struct {
VolumeAttributesClassName *string `json:"volumeAttributesClassName,omitempty"`
}

// TiCITiDBAuth contains TiDB auth settings used by TiCI.
// +k8s:openapi-gen=true
type TiCITiDBAuth struct {
// User is the TiDB user used by TiCI meta. Defaults to root.
// +optional
User string `json:"user,omitempty"`

// PasswordSecret selects the Secret key that stores the TiDB auth data.
// The referenced Secret key is required; optional must not be true.
// +kubebuilder:validation:Required
Comment on lines +1027 to +1028
// +kubebuilder:validation:XValidation:rule="!has(self.optional) || self.optional == false",message="optional must be false because TiCI meta TiDB auth Secret is required"
PasswordSecret *corev1.SecretKeySelector `json:"passwordSecret"`
}

// TiCIWorkerSpec contains details of TiCI worker members
// +k8s:openapi-gen=true
type TiCIWorkerSpec struct {
Expand Down
18 changes: 18 additions & 0 deletions pkg/apis/pingcap/v1alpha1/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ func validateTiCISpec(spec *v1alpha1.TiCISpec, fldPath *field.Path) field.ErrorL
if len(spec.Meta.StorageVolumes) > 0 {
allErrs = append(allErrs, validateStorageVolumes(spec.Meta.StorageVolumes, fldPath.Child("meta", "storageVolumes"))...)
}
if spec.Meta.TiDBAuth != nil {
allErrs = append(allErrs, validateTiCITiDBAuth(spec.Meta.TiDBAuth, fldPath.Child("meta", "tidbAuth"))...)
}
}
if spec.Worker == nil {
allErrs = append(allErrs, field.Required(fldPath.Child("worker"), "worker is required when tici is enabled"))
Expand Down Expand Up @@ -281,6 +284,21 @@ func validateTiKVSpec(spec *v1alpha1.TiKVSpec, fldPath *field.Path) field.ErrorL
return allErrs
}

func validateTiCITiDBAuth(auth *v1alpha1.TiCITiDBAuth, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if auth.PasswordSecret == nil {
allErrs = append(allErrs, field.Required(fldPath.Child("passwordSecret"), "passwordSecret is required when tidbAuth is set"))
} else {
allErrs = append(allErrs, validateSecretKeySelector(auth.PasswordSecret, fldPath.Child("passwordSecret"))...)
if auth.PasswordSecret.Optional != nil && *auth.PasswordSecret.Optional {
allErrs = append(allErrs, field.Invalid(fldPath.Child("passwordSecret", "optional"), *auth.PasswordSecret.Optional, "optional must be false because TiCI meta TiDB auth Secret is required"))
}
}

return allErrs
}

func validateTiFlashSpec(spec *v1alpha1.TiFlashSpec, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, validateComponentSpec(&spec.ComponentSpec, fldPath)...)
Expand Down
58 changes: 58 additions & 0 deletions pkg/apis/pingcap/v1alpha1/validation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,64 @@ func TestValidateDMAnnotations(t *testing.T) {
}
}

func TestValidateTiCITiDBAuth(t *testing.T) {
tests := []struct {
name string
auth *v1alpha1.TiCITiDBAuth
expectedErrs int
expectedField string
}{
{
name: "valid password secret",
auth: &v1alpha1.TiCITiDBAuth{
PasswordSecret: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{Name: "tidb-auth"},
Key: "auth",
},
},
},
{
name: "optional false is valid",
auth: &v1alpha1.TiCITiDBAuth{
PasswordSecret: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{Name: "tidb-auth"},
Key: "auth",
Optional: pointer.BoolPtr(false),
},
},
},
{
name: "password secret is required",
auth: &v1alpha1.TiCITiDBAuth{},
expectedErrs: 1,
expectedField: "spec.tici.meta.tidbAuth.passwordSecret",
},
{
name: "optional true is forbidden",
auth: &v1alpha1.TiCITiDBAuth{
PasswordSecret: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{Name: "tidb-auth"},
Key: "auth",
Optional: pointer.BoolPtr(true),
},
},
expectedErrs: 1,
expectedField: "spec.tici.meta.tidbAuth.passwordSecret.optional",
},
}

for _, tt := range tests {
errs := validateTiCITiDBAuth(tt.auth, field.NewPath("spec", "tici", "meta", "tidbAuth"))
if len(errs) != tt.expectedErrs {
t.Errorf("[%s]: expected %d failures, got %d failures: %v", tt.name, tt.expectedErrs, len(errs), errs)
continue
}
if tt.expectedField != "" && errs[0].Field != tt.expectedField {
t.Errorf("[%s]: expected error field %q, got %q", tt.name, tt.expectedField, errs[0].Field)
}
}
}

func TestValidatePumpSpec(t *testing.T) {
g := NewGomegaWithT(t)
tests := []struct {
Expand Down
26 changes: 26 additions & 0 deletions pkg/apis/pingcap/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading