Skip to content

Commit

Permalink
chore: support to update and delete system accounts (#8756)
Browse files Browse the repository at this point in the history
  • Loading branch information
leon-inf authored Jan 21, 2025
1 parent 309ab9c commit 2b312c3
Show file tree
Hide file tree
Showing 29 changed files with 1,024 additions and 453 deletions.
30 changes: 23 additions & 7 deletions apis/apps/v1/componentdefinition_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1222,26 +1222,42 @@ type SystemAccount struct {
// +optional
InitAccount bool `json:"initAccount,omitempty"`

// Defines the statement used to create the account with the necessary privileges.
// Defines the statements used to create, delete, and update the account.
//
// This field is immutable once set.
//
// +optional
Statement string `json:"statement,omitempty"`
Statement *SystemAccountStatement `json:"statement,omitempty"`

// Specifies the policy for generating the account's password.
//
// This field is immutable once set.
//
// +optional
PasswordGenerationPolicy PasswordConfig `json:"passwordGenerationPolicy"`
}

type SystemAccountStatement struct {
// The statement to create a new account with the necessary privileges.
//
// This field is immutable once set.
//
// +optional
Create string `json:"create,omitempty"`

// The statement to delete a account.
//
// This field is immutable once set.
//
// +optional
Delete string `json:"delete,omitempty"`

// Refers to the secret from which data will be copied to create the new account.
// The statement to update an existing account.
//
// This field is immutable once set.
//
// +optional
SecretRef *ProvisionSecretRef `json:"secretRef,omitempty"`
Update string `json:"update,omitempty"`
}

type TLS struct {
Expand Down Expand Up @@ -1757,9 +1773,9 @@ type ComponentLifecycleActions struct {
//
// The container executing this action has access to following variables:
//
// - KB_ACCOUNT_NAME: The name of the system account to be created.
// - KB_ACCOUNT_PASSWORD: The password for the system account. // TODO: how to pass the password securely?
// - KB_ACCOUNT_STATEMENT: The statement used to create the system account.
// - KB_ACCOUNT_NAME: The name of the system account to be manipulated.
// - KB_ACCOUNT_PASSWORD: The password for the system account.
// - KB_ACCOUNT_STATEMENT: The statement used to manipulate the system account.
//
// Note: This field is immutable once it has been set.
//
Expand Down
14 changes: 14 additions & 0 deletions apis/apps/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,12 @@ type ComponentSystemAccount struct {
// +kubebuilder:validation:Required
Name string `json:"name"`

// Specifies whether the system account is disabled.
//
// +kubebuilder:default=false
// +optional
Disabled *bool `json:"disabled,omitempty"`

// Specifies the policy for generating the account's password.
//
// This field is immutable once set.
Expand All @@ -363,6 +369,8 @@ type ComponentSystemAccount struct {

// Refers to the secret from which data will be copied to create the new account.
//
// For user-specified passwords, the maximum length is limited to 64 bytes.
//
// This field is immutable once set.
//
// +optional
Expand Down Expand Up @@ -436,6 +444,12 @@ type ProvisionSecretRef struct {
//
// +kubebuilder:validation:Required
Namespace string `json:"namespace"`

// The key in the secret data that contains the password.
//
// +kubebuilder:default="password"
// +optional
Password string `json:"password,omitempty"`
}

// ClusterComponentConfig represents a config with its source bound.
Expand Down
28 changes: 24 additions & 4 deletions apis/apps/v1/zz_generated.deepcopy.go

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

25 changes: 25 additions & 0 deletions config/crd/bases/apps.kubeblocks.io_clusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5323,6 +5323,10 @@ spec:
ComponentDefinition.
items:
properties:
disabled:
default: false
description: Specifies whether the system account is disabled.
type: boolean
name:
description: The name of the system account.
type: string
Expand Down Expand Up @@ -5373,6 +5377,9 @@ spec:
Refers to the secret from which data will be copied to create the new account.


For user-specified passwords, the maximum length is limited to 64 bytes.


This field is immutable once set.
properties:
name:
Expand All @@ -5381,6 +5388,11 @@ spec:
namespace:
description: The namespace where the secret is located.
type: string
password:
default: password
description: The key in the secret data that contains
the password.
type: string
required:
- name
- namespace
Expand Down Expand Up @@ -14070,6 +14082,11 @@ spec:
ComponentDefinition.
items:
properties:
disabled:
default: false
description: Specifies whether the system account
is disabled.
type: boolean
name:
description: The name of the system account.
type: string
Expand Down Expand Up @@ -14120,6 +14137,9 @@ spec:
Refers to the secret from which data will be copied to create the new account.


For user-specified passwords, the maximum length is limited to 64 bytes.


This field is immutable once set.
properties:
name:
Expand All @@ -14129,6 +14149,11 @@ spec:
description: The namespace where the secret is
located.
type: string
password:
default: password
description: The key in the secret data that contains
the password.
type: string
required:
- name
- namespace
Expand Down
41 changes: 23 additions & 18 deletions config/crd/bases/apps.kubeblocks.io_componentdefinitions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4501,9 +4501,9 @@ spec:
The container executing this action has access to following variables:


- KB_ACCOUNT_NAME: The name of the system account to be created.
- KB_ACCOUNT_PASSWORD: The password for the system account. // TODO: how to pass the password securely?
- KB_ACCOUNT_STATEMENT: The statement used to create the system account.
- KB_ACCOUNT_NAME: The name of the system account to be manipulated.
- KB_ACCOUNT_PASSWORD: The password for the system account.
- KB_ACCOUNT_STATEMENT: The statement used to manipulate the system account.


Note: This field is immutable once it has been set.
Expand Down Expand Up @@ -16740,30 +16740,35 @@ spec:
Cannot be updated.
type: string
type: object
secretRef:
statement:
description: |-
Refers to the secret from which data will be copied to create the new account.
Defines the statements used to create, delete, and update the account.


This field is immutable once set.
properties:
name:
description: The unique identifier of the secret.
create:
description: |-
The statement to create a new account with the necessary privileges.


This field is immutable once set.
type: string
namespace:
description: The namespace where the secret is located.
delete:
description: |-
The statement to delete a account.


This field is immutable once set.
type: string
required:
- name
- namespace
type: object
statement:
description: |-
Defines the statement used to create the account with the necessary privileges.
update:
description: |-
The statement to update an existing account.


This field is immutable once set.
type: string
This field is immutable once set.
type: string
type: object
required:
- name
type: object
Expand Down
12 changes: 12 additions & 0 deletions config/crd/bases/apps.kubeblocks.io_components.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5510,6 +5510,10 @@ spec:
description: Overrides system accounts defined in referenced ComponentDefinition.
items:
properties:
disabled:
default: false
description: Specifies whether the system account is disabled.
type: boolean
name:
description: The name of the system account.
type: string
Expand Down Expand Up @@ -5560,6 +5564,9 @@ spec:
Refers to the secret from which data will be copied to create the new account.


For user-specified passwords, the maximum length is limited to 64 bytes.


This field is immutable once set.
properties:
name:
Expand All @@ -5568,6 +5575,11 @@ spec:
namespace:
description: The namespace where the secret is located.
type: string
password:
default: password
description: The key in the secret data that contains the
password.
type: string
required:
- name
- namespace
Expand Down
1 change: 1 addition & 0 deletions controllers/apps/cluster/transformer_cluster_component.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ func copyAndMergeComponent(oldCompObj, newCompObj *appsv1.Component) *appsv1.Com
compObjCopy.Spec.VolumeClaimTemplates = compProto.Spec.VolumeClaimTemplates
compObjCopy.Spec.Volumes = compProto.Spec.Volumes
compObjCopy.Spec.Services = compProto.Spec.Services
compObjCopy.Spec.SystemAccounts = compProto.Spec.SystemAccounts
compObjCopy.Spec.Replicas = compProto.Spec.Replicas
compObjCopy.Spec.Configs = compProto.Spec.Configs
compObjCopy.Spec.ServiceAccountName = compProto.Spec.ServiceAccountName
Expand Down
39 changes: 7 additions & 32 deletions controllers/apps/cluster/transformer_cluster_sharding_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,17 +118,7 @@ func (t *clusterShardingAccountTransformer) newSystemAccountSecret(transCtx *clu
if err != nil {
return nil, err
}

var password []byte
switch {
case account.SecretRef != nil:
var err error
if password, err = t.getPasswordFromSecret(transCtx, account); err != nil {
return nil, err
}
default:
password = t.buildPassword(transCtx, account, sharding.Name)
}
password := t.buildPassword(transCtx, account, sharding.Name)
return t.newAccountSecretWithPassword(transCtx, sharding, accountName, password)
}

Expand All @@ -152,7 +142,6 @@ func (t *clusterShardingAccountTransformer) definedSystemAccount(transCtx *clust
if compAccount.PasswordConfig != nil {
account.PasswordGenerationPolicy = *compAccount.PasswordConfig
}
account.SecretRef = compAccount.SecretRef
}
return *account
}
Expand All @@ -165,21 +154,6 @@ func (t *clusterShardingAccountTransformer) definedSystemAccount(transCtx *clust
return appsv1.SystemAccount{}, fmt.Errorf("system account %s not found in component definition %s", accountName, compDef.Name)
}

func (t *clusterShardingAccountTransformer) getPasswordFromSecret(ctx graph.TransformContext, account appsv1.SystemAccount) ([]byte, error) {
secretKey := types.NamespacedName{
Namespace: account.SecretRef.Namespace,
Name: account.SecretRef.Name,
}
secret := &corev1.Secret{}
if err := ctx.GetClient().Get(ctx.GetContext(), secretKey, secret); err != nil {
return nil, err
}
if len(secret.Data) == 0 || len(secret.Data[constant.AccountPasswdForSecret]) == 0 {
return nil, fmt.Errorf("referenced account secret has no required credential field")
}
return secret.Data[constant.AccountPasswdForSecret], nil
}

func (t *clusterShardingAccountTransformer) buildPassword(transCtx *clusterTransformContext, account appsv1.SystemAccount, shardingName string) []byte {
password := []byte(factory.GetRestoreSystemAccountPassword(transCtx.Cluster.Annotations, shardingName, account.Name))
if len(password) == 0 {
Expand Down Expand Up @@ -227,20 +201,21 @@ func (t *clusterShardingAccountTransformer) rewriteSystemAccount(transCtx *clust
var (
cluster = transCtx.Cluster
)
account := appsv1.ComponentSystemAccount{
newAccount := appsv1.ComponentSystemAccount{
Name: accountName,
SecretRef: &appsv1.ProvisionSecretRef{
Name: shardingAccountSecretName(cluster.Name, sharding.Name, accountName),
Namespace: cluster.Namespace,
},
}
for i := range sharding.Template.SystemAccounts {
if sharding.Template.SystemAccounts[i].Name == accountName {
sharding.Template.SystemAccounts[i] = account
for i, account := range sharding.Template.SystemAccounts {
if account.Name == accountName {
newAccount.Disabled = account.Disabled
sharding.Template.SystemAccounts[i] = newAccount
return
}
}
sharding.Template.SystemAccounts = []appsv1.ComponentSystemAccount{account}
sharding.Template.SystemAccounts = []appsv1.ComponentSystemAccount{newAccount}
}

func shardingAccountSecretName(cluster, sharding, account string) string {
Expand Down
Loading

0 comments on commit 2b312c3

Please sign in to comment.