From c6fae07817f560ba7f123659aa5bde9a5463abf7 Mon Sep 17 00:00:00 2001 From: Chris Sun <85611200+chris-sun-star@users.noreply.github.com> Date: Thu, 14 Nov 2024 14:38:13 +0800 Subject: [PATCH] support tenant parameter management (#629) --- api/types/types.go | 2 + api/v1alpha1/obparameter_types.go | 2 + api/v1alpha1/obtenant_types.go | 16 +-- api/v1alpha1/zz_generated.deepcopy.go | 7 ++ .../oceanbase.oceanbase.com_obparameters.yaml | 5 + ....oceanbase.com_obtenantbackuppolicies.yaml | 24 +++++ ...base.oceanbase.com_obtenantoperations.yaml | 48 +++++++++ .../oceanbase.oceanbase.com_obtenants.yaml | 24 +++++ deploy/operator.yaml | 101 ++++++++++++++++++ internal/const/oceanbase/labels.go | 1 + .../status/tenantstatus/obtenant_status.go | 1 + .../resource/obcluster/obcluster_manager.go | 4 +- internal/resource/obcluster/utils.go | 2 +- .../obparameter/obparameter_manager.go | 4 + .../resource/obparameter/obparameter_task.go | 10 +- internal/resource/obparameter/utils.go | 2 +- internal/resource/obtenant/obtenant_flow.go | 12 +++ .../resource/obtenant/obtenant_manager.go | 46 +++++++- internal/resource/obtenant/obtenant_task.go | 39 +++++++ .../resource/obtenant/obtenant_task_gen.go | 1 + .../obtenant/obtenant_taskname_gen.go | 1 + internal/resource/obtenant/utils.go | 90 ++++++++++++++++ pkg/oceanbase-sdk/const/sql/parameter.go | 4 +- 23 files changed, 432 insertions(+), 14 deletions(-) diff --git a/api/types/types.go b/api/types/types.go index e611a7384..379f26960 100644 --- a/api/types/types.go +++ b/api/types/types.go @@ -33,3 +33,5 @@ type TenantOperationType string type ClusterOperationType string type ClusterOperationStatus string + +type ParameterScope string diff --git a/api/v1alpha1/obparameter_types.go b/api/v1alpha1/obparameter_types.go index c16024941..bc51632e5 100644 --- a/api/v1alpha1/obparameter_types.go +++ b/api/v1alpha1/obparameter_types.go @@ -32,6 +32,8 @@ type OBParameterSpec struct { // Important: Run "make" to regenerate code after modifying this file ClusterName string `json:"clusterName"` ClusterId int64 `json:"clusterId,omitempty"` + TenantName string `json:"tenantName,omitempty"` + TenantId int64 `json:"tenantId,omitempty"` Parameter *apitypes.Parameter `json:"parameter"` } diff --git a/api/v1alpha1/obtenant_types.go b/api/v1alpha1/obtenant_types.go index b9a0bbb99..dedb225ca 100644 --- a/api/v1alpha1/obtenant_types.go +++ b/api/v1alpha1/obtenant_types.go @@ -47,10 +47,11 @@ type OBTenantSpec struct { Pools []ResourcePoolSpec `json:"pools"` //+kubebuilder:default=PRIMARY - TenantRole apitypes.TenantRole `json:"tenantRole,omitempty"` - Source *TenantSourceSpec `json:"source,omitempty"` - Credentials TenantCredentials `json:"credentials,omitempty"` - Scenario string `json:"scenario,omitempty"` + TenantRole apitypes.TenantRole `json:"tenantRole,omitempty"` + Source *TenantSourceSpec `json:"source,omitempty"` + Credentials TenantCredentials `json:"credentials,omitempty"` + Scenario string `json:"scenario,omitempty"` + Parameters []apitypes.Parameter `json:"parameters,omitempty"` } type TenantCredentials struct { @@ -101,9 +102,10 @@ type OBTenantStatus struct { OperationContext *tasktypes.OperationContext `json:"operationContext,omitempty"` TenantRecordInfo TenantRecordInfo `json:"tenantRecordInfo,omitempty"` - TenantRole apitypes.TenantRole `json:"tenantRole,omitempty"` - Source *TenantSourceStatus `json:"source,omitempty"` - Credentials TenantCredentials `json:"credentials,omitempty"` + TenantRole apitypes.TenantRole `json:"tenantRole,omitempty"` + Source *TenantSourceStatus `json:"source,omitempty"` + Credentials TenantCredentials `json:"credentials,omitempty"` + Parameters []apitypes.Parameter `json:"parameters,omitempty"` } type TenantSourceStatus struct { diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 1599edf84..ee3152368 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1351,6 +1351,13 @@ func (in *OBTenantSpec) DeepCopyInto(out *OBTenantSpec) { (*in).DeepCopyInto(*out) } out.Credentials = in.Credentials + if in.Parameters != nil { + in, out := &in.Parameters, &out.Parameters + *out = make([]types.Parameter, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OBTenantSpec. diff --git a/config/crd/bases/oceanbase.oceanbase.com_obparameters.yaml b/config/crd/bases/oceanbase.oceanbase.com_obparameters.yaml index f7e368272..8ae92482b 100644 --- a/config/crd/bases/oceanbase.oceanbase.com_obparameters.yaml +++ b/config/crd/bases/oceanbase.oceanbase.com_obparameters.yaml @@ -73,6 +73,11 @@ spec: - name - value type: object + tenantId: + format: int64 + type: integer + tenantName: + type: string required: - clusterName - parameter diff --git a/config/crd/bases/oceanbase.oceanbase.com_obtenantbackuppolicies.yaml b/config/crd/bases/oceanbase.oceanbase.com_obtenantbackuppolicies.yaml index cc995efe5..684c484e7 100644 --- a/config/crd/bases/oceanbase.oceanbase.com_obtenantbackuppolicies.yaml +++ b/config/crd/bases/oceanbase.oceanbase.com_obtenantbackuppolicies.yaml @@ -484,6 +484,18 @@ spec: type: boolean obcluster: type: string + parameters: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array pools: items: properties: @@ -679,6 +691,18 @@ spec: - taskStatus - tasks type: object + parameters: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array resourcePool: items: properties: diff --git a/config/crd/bases/oceanbase.oceanbase.com_obtenantoperations.yaml b/config/crd/bases/oceanbase.oceanbase.com_obtenantoperations.yaml index 1edc7852e..d1e0a9f43 100644 --- a/config/crd/bases/oceanbase.oceanbase.com_obtenantoperations.yaml +++ b/config/crd/bases/oceanbase.oceanbase.com_obtenantoperations.yaml @@ -340,6 +340,18 @@ spec: type: boolean obcluster: type: string + parameters: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array pools: items: properties: @@ -535,6 +547,18 @@ spec: - taskStatus - tasks type: object + parameters: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array resourcePool: items: properties: @@ -865,6 +889,18 @@ spec: type: boolean obcluster: type: string + parameters: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array pools: items: properties: @@ -1060,6 +1096,18 @@ spec: - taskStatus - tasks type: object + parameters: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array resourcePool: items: properties: diff --git a/config/crd/bases/oceanbase.oceanbase.com_obtenants.yaml b/config/crd/bases/oceanbase.oceanbase.com_obtenants.yaml index c3e986956..8e1e853fa 100644 --- a/config/crd/bases/oceanbase.oceanbase.com_obtenants.yaml +++ b/config/crd/bases/oceanbase.oceanbase.com_obtenants.yaml @@ -91,6 +91,18 @@ spec: type: boolean obcluster: type: string + parameters: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array pools: items: properties: @@ -286,6 +298,18 @@ spec: - taskStatus - tasks type: object + parameters: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array resourcePool: items: properties: diff --git a/deploy/operator.yaml b/deploy/operator.yaml index cce6e8a44..b71b3c6a4 100644 --- a/deploy/operator.yaml +++ b/deploy/operator.yaml @@ -10290,6 +10290,11 @@ spec: - name - value type: object + tenantId: + format: int64 + type: integer + tenantName: + type: string required: - clusterName - parameter @@ -14052,6 +14057,18 @@ spec: type: boolean obcluster: type: string + parameters: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array pools: items: properties: @@ -14247,6 +14264,18 @@ spec: - taskStatus - tasks type: object + parameters: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array resourcePool: items: properties: @@ -15311,6 +15340,18 @@ spec: type: boolean obcluster: type: string + parameters: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array pools: items: properties: @@ -15506,6 +15547,18 @@ spec: - taskStatus - tasks type: object + parameters: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array resourcePool: items: properties: @@ -15836,6 +15889,18 @@ spec: type: boolean obcluster: type: string + parameters: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array pools: items: properties: @@ -16031,6 +16096,18 @@ spec: - taskStatus - tasks type: object + parameters: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array resourcePool: items: properties: @@ -16717,6 +16794,18 @@ spec: type: boolean obcluster: type: string + parameters: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array pools: items: properties: @@ -16912,6 +17001,18 @@ spec: - taskStatus - tasks type: object + parameters: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array resourcePool: items: properties: diff --git a/internal/const/oceanbase/labels.go b/internal/const/oceanbase/labels.go index 99204537f..f60534b02 100644 --- a/internal/const/oceanbase/labels.go +++ b/internal/const/oceanbase/labels.go @@ -13,6 +13,7 @@ See the Mulan PSL v2 for more details. package oceanbase const ( + LabelRefOBTenant = "ref-obtenant" LabelRefOBCluster = "ref-obcluster" LabelRefOBZone = "ref-obzone" LabelRefOBServer = "ref-observer" diff --git a/internal/const/status/tenantstatus/obtenant_status.go b/internal/const/status/tenantstatus/obtenant_status.go index 4a3461cc1..ebde90e69 100644 --- a/internal/const/status/tenantstatus/obtenant_status.go +++ b/internal/const/status/tenantstatus/obtenant_status.go @@ -23,6 +23,7 @@ const ( AddingResourcePool = "adding resource pool" DeletingResourcePool = "deleting resource pool" MaintainingUnitConfig = "maintaining unit config" + MaintainingParameters = "maintaining parameters" DeletingTenant = "deleting" FinalizerFinished = "finalizer finished" PausingReconcile = "pausing reconcile" diff --git a/internal/resource/obcluster/obcluster_manager.go b/internal/resource/obcluster/obcluster_manager.go index ea831e9e6..46462dc82 100644 --- a/internal/resource/obcluster/obcluster_manager.go +++ b/internal/resource/obcluster/obcluster_manager.go @@ -163,7 +163,9 @@ func (m *OBClusterManager) UpdateStatus() error { } obparameterStatusList := make([]apitypes.Parameter, 0) for _, obparameter := range obparameterList.Items { - obparameterStatusList = append(obparameterStatusList, *(obparameter.Spec.Parameter)) + if obparameter.Spec.TenantName == "" { + obparameterStatusList = append(obparameterStatusList, *(obparameter.Spec.Parameter)) + } } m.OBCluster.Status.Parameters = obparameterStatusList diff --git a/internal/resource/obcluster/utils.go b/internal/resource/obcluster/utils.go index 37521c4b3..2fb4a6645 100644 --- a/internal/resource/obcluster/utils.go +++ b/internal/resource/obcluster/utils.go @@ -92,7 +92,7 @@ func (m *OBClusterManager) listOBParameters() (*v1alpha1.OBParameterList, error) oceanbaseconst.LabelRefOBCluster: m.OBCluster.Name, }, client.InNamespace(m.OBCluster.Namespace)) if err != nil { - return nil, errors.Wrap(err, "get obzone list") + return nil, errors.Wrap(err, "get obparameter list") } return obparameterList, nil } diff --git a/internal/resource/obparameter/obparameter_manager.go b/internal/resource/obparameter/obparameter_manager.go index 0bce3e03b..c69527812 100644 --- a/internal/resource/obparameter/obparameter_manager.go +++ b/internal/resource/obparameter/obparameter_manager.go @@ -122,6 +122,10 @@ func (m *OBParameterManager) UpdateStatus() error { parameterMatched := true parameterValues := make([]apitypes.ParameterValue, 0) for _, parameterInfo := range parameterInfoList { + // filter out parameters + if (m.OBParameter.Spec.TenantName == "" && parameterInfo.TenantID > 1) || (m.OBParameter.Spec.TenantName != "" && parameterInfo.TenantID != m.OBParameter.Spec.TenantId) { + continue + } parameterValue := apitypes.ParameterValue{ Name: parameterInfo.Name, Value: parameterInfo.Value, diff --git a/internal/resource/obparameter/obparameter_task.go b/internal/resource/obparameter/obparameter_task.go index 7eb341b6f..d961f06ec 100644 --- a/internal/resource/obparameter/obparameter_task.go +++ b/internal/resource/obparameter/obparameter_task.go @@ -15,6 +15,7 @@ package obparameter import ( "github.com/pkg/errors" + "github.com/oceanbase/ob-operator/pkg/oceanbase-sdk/param" "github.com/oceanbase/ob-operator/pkg/task/builder" tasktypes "github.com/oceanbase/ob-operator/pkg/task/types" ) @@ -29,7 +30,14 @@ func SetOBParameter(m *OBParameterManager) tasktypes.TaskError { m.Logger.Error(err, "Get operation manager failed") return errors.Wrapf(err, "Get operation manager") } - err = operationManager.SetParameter(m.Ctx, m.OBParameter.Spec.Parameter.Name, m.OBParameter.Spec.Parameter.Value, nil) + var scope *param.Scope + if m.OBParameter.Spec.TenantName != "" { + scope = ¶m.Scope{ + Name: "tenant", + Value: m.OBParameter.Spec.TenantName, + } + } + err = operationManager.SetParameter(m.Ctx, m.OBParameter.Spec.Parameter.Name, m.OBParameter.Spec.Parameter.Value, scope) if err != nil { m.Logger.Error(err, "Set parameter failed") return errors.Wrapf(err, "Set parameter") diff --git a/internal/resource/obparameter/utils.go b/internal/resource/obparameter/utils.go index 608864ad9..998a82a2d 100644 --- a/internal/resource/obparameter/utils.go +++ b/internal/resource/obparameter/utils.go @@ -37,7 +37,7 @@ func (m *OBParameterManager) getOBCluster() (*v1alpha1.OBCluster, error) { obcluster := &v1alpha1.OBCluster{} err := m.Client.Get(m.Ctx, m.generateNamespacedName(clusterName), obcluster) if err != nil { - return nil, errors.Wrap(err, "get obcluster") + return nil, errors.Wrap(err, "Get obcluster") } return obcluster, nil } diff --git a/internal/resource/obtenant/obtenant_flow.go b/internal/resource/obtenant/obtenant_flow.go index 0ae41bbf4..873085f3d 100644 --- a/internal/resource/obtenant/obtenant_flow.go +++ b/internal/resource/obtenant/obtenant_flow.go @@ -186,3 +186,15 @@ func genCreateEmptyStandbyTenantFlow(_ *OBTenantManager) *tasktypes.TaskFlow { }, } } + +func genMaintainTenantParametersFlow(_ *OBTenantManager) *tasktypes.TaskFlow { + return &tasktypes.TaskFlow{ + OperationContext: &tasktypes.OperationContext{ + Name: "maintain tenant parameters", + Tasks: []tasktypes.TaskName{ + tMaintainTenantParameters, + }, + TargetStatus: tenantstatus.Running, + }, + } +} diff --git a/internal/resource/obtenant/obtenant_manager.go b/internal/resource/obtenant/obtenant_manager.go index 957f222cb..75d2ff79f 100644 --- a/internal/resource/obtenant/obtenant_manager.go +++ b/internal/resource/obtenant/obtenant_manager.go @@ -29,6 +29,7 @@ import ( "k8s.io/client-go/util/retry" "sigs.k8s.io/controller-runtime/pkg/client" + apitypes "github.com/oceanbase/ob-operator/api/types" "github.com/oceanbase/ob-operator/api/v1alpha1" oceanbaseconst "github.com/oceanbase/ob-operator/internal/const/oceanbase" "github.com/oceanbase/ob-operator/internal/const/status/tenantstatus" @@ -172,7 +173,7 @@ func (m *OBTenantManager) UpdateStatus() error { // build tenant status from DB tenantStatusCurrent, err := m.buildTenantStatus() if err != nil { - m.Logger.Error(err, "Got error when build obtenant status from DB") + m.Logger.Error(err, "Got error when build obtenant status") return err } m.OBTenant.Status = *tenantStatusCurrent @@ -276,6 +277,8 @@ func (m *OBTenantManager) GetTaskFlow() (*tasktypes.TaskFlow, error) { taskFlow = genCancelRestoreFlow(m) case tenantstatus.CreatingEmptyStandby: taskFlow = genCreateEmptyStandbyTenantFlow(m) + case tenantstatus.MaintainingParameters: + taskFlow = genMaintainTenantParametersFlow(m) default: m.Logger.V(oceanbaseconst.LogLevelTrace).Info("No need to run anything for obtenant") return nil, nil @@ -374,6 +377,9 @@ func (m *OBTenantManager) NextStatus() (string, error) { if hasModifiedUnitConfig { return tenantstatus.MaintainingUnitConfig, nil } + if m.hasModifiedParameters() { + return tenantstatus.MaintainingParameters, nil + } return tenantstatus.Running, nil } @@ -392,6 +398,30 @@ func (m *OBTenantManager) hasModifiedWhiteList() bool { return false } +func (m *OBTenantManager) hasModifiedParameters() bool { + parameterModified := false + parameterMap := make(map[string]apitypes.Parameter) + for _, parameter := range m.OBTenant.Status.Parameters { + m.Logger.V(oceanbaseconst.LogLevelDebug).Info("Build parameter map", "parameter", parameter.Name) + parameterMap[parameter.Name] = parameter + } + for _, parameter := range m.OBTenant.Spec.Parameters { + parameterStatus, parameterExists := parameterMap[parameter.Name] + // need create or update parameter + if !parameterExists || parameterStatus.Value != parameter.Value { + parameterModified = true + break + } + delete(parameterMap, parameter.Name) + } + + // need delete parameter + if len(parameterMap) > 0 { + parameterModified = true + } + return parameterModified +} + func (m *OBTenantManager) hasModifiedUnitConfig() (bool, error) { tenantName := m.OBTenant.Spec.TenantName @@ -549,6 +579,20 @@ func (m *OBTenantManager) buildTenantStatus() (*v1alpha1.OBTenantStatus, error) tenantCurrentStatus.Credentials.Root = m.OBTenant.Spec.Credentials.Root } + // Refresh parameter info + obparameterList, err := m.listOBParameters() + if err != nil { + m.Logger.Error(err, "list obparameters error") + return tenantCurrentStatus, errors.Wrap(err, "list obparameters") + } + obparameterStatusList := make([]apitypes.Parameter, 0) + for _, obparameter := range obparameterList.Items { + if obparameter.Spec.TenantName == m.OBTenant.Spec.TenantName { + obparameterStatusList = append(obparameterStatusList, *(obparameter.Spec.Parameter)) + } + } + tenantCurrentStatus.Parameters = obparameterStatusList + return tenantCurrentStatus, nil } diff --git a/internal/resource/obtenant/obtenant_task.go b/internal/resource/obtenant/obtenant_task.go index 6fdf12098..a8a60d908 100644 --- a/internal/resource/obtenant/obtenant_task.go +++ b/internal/resource/obtenant/obtenant_task.go @@ -28,6 +28,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/oceanbase/ob-operator/api/constants" + apitypes "github.com/oceanbase/ob-operator/api/types" "github.com/oceanbase/ob-operator/api/v1alpha1" obcfg "github.com/oceanbase/ob-operator/internal/config/operator" cmdconst "github.com/oceanbase/ob-operator/internal/const/cmd" @@ -569,3 +570,41 @@ func CreateUserWithCredentialSecrets(m *OBTenantManager) tasktypes.TaskError { return nil } + +func MaintainTenantParameters(m *OBTenantManager) tasktypes.TaskError { + parameterMap := make(map[string]apitypes.Parameter) + for _, parameter := range m.OBTenant.Status.Parameters { + m.Logger.V(oceanbaseconst.LogLevelDebug).Info("Build parameter map", "parameter", parameter.Name) + parameterMap[parameter.Name] = parameter + } + for _, parameter := range m.OBTenant.Spec.Parameters { + parameterStatus, parameterExists := parameterMap[parameter.Name] + if !parameterExists { + m.Logger.V(oceanbaseconst.LogLevelDebug).Info("Parameter not exists, need create", "param", parameter.Name) + err := m.createOBParameter(¶meter) + if err != nil { + // since parameter is not a big problem, just log the error + m.Logger.Error(err, "Create obparameter failed", "param", parameter.Name) + } + } else if parameterStatus.Value != parameter.Value { + m.Logger.V(oceanbaseconst.LogLevelDebug).Info("Parameter value not matched, need update", "param", parameter.Name) + err := m.updateOBParameter(¶meter) + if err != nil { + // since parameter is not a big problem, just log the error + m.Logger.Error(err, "Update obparameter failed", "param", parameter.Name) + } + } + m.Logger.V(oceanbaseconst.LogLevelDebug).Info("Remove parameter from map", "parameter", parameter.Name) + delete(parameterMap, parameter.Name) + } + + // delete parameters that not in spec definition + for _, parameter := range parameterMap { + m.Logger.V(oceanbaseconst.LogLevelDebug).Info("Delete parameter", "parameter", parameter.Name) + err := m.deleteOBParameter(¶meter) + if err != nil { + m.Logger.Error(err, "Failed to delete parameter") + } + } + return nil +} diff --git a/internal/resource/obtenant/obtenant_task_gen.go b/internal/resource/obtenant/obtenant_task_gen.go index f7a99b0aa..e1b3cc0ba 100644 --- a/internal/resource/obtenant/obtenant_task_gen.go +++ b/internal/resource/obtenant/obtenant_task_gen.go @@ -23,4 +23,5 @@ func init() { taskMap.Register(tCheckAndApplyLocality, CheckAndApplyLocality) taskMap.Register(tOptimizeTenantByScenario, OptimizeTenantByScenario) taskMap.Register(tCreateUserWithCredentialSecrets, CreateUserWithCredentialSecrets) + taskMap.Register(tMaintainTenantParameters, MaintainTenantParameters) } diff --git a/internal/resource/obtenant/obtenant_taskname_gen.go b/internal/resource/obtenant/obtenant_taskname_gen.go index 9cb6e5cba..fcac3c19e 100644 --- a/internal/resource/obtenant/obtenant_taskname_gen.go +++ b/internal/resource/obtenant/obtenant_taskname_gen.go @@ -25,4 +25,5 @@ const ( tCheckAndApplyLocality ttypes.TaskName = "check and apply locality" tOptimizeTenantByScenario ttypes.TaskName = "optimize tenant by scenario" tCreateUserWithCredentialSecrets ttypes.TaskName = "create user with credential secrets" + tMaintainTenantParameters ttypes.TaskName = "maintain tenant parameters" ) diff --git a/internal/resource/obtenant/utils.go b/internal/resource/obtenant/utils.go index d2e137346..1d9d947cd 100644 --- a/internal/resource/obtenant/utils.go +++ b/internal/resource/obtenant/utils.go @@ -24,8 +24,10 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/rand" + "k8s.io/client-go/util/retry" "sigs.k8s.io/controller-runtime/pkg/client" + apitypes "github.com/oceanbase/ob-operator/api/types" "github.com/oceanbase/ob-operator/api/v1alpha1" oceanbaseconst "github.com/oceanbase/ob-operator/internal/const/oceanbase" resourceutils "github.com/oceanbase/ob-operator/internal/resource/utils" @@ -920,3 +922,91 @@ func CreateUserWithCredentials(m *OBTenantManager) error { } return nil } + +func (m *OBTenantManager) listOBParameters() (*v1alpha1.OBParameterList, error) { + obparameterList := &v1alpha1.OBParameterList{} + err := m.Client.List(m.Ctx, obparameterList, client.MatchingLabels{ + oceanbaseconst.LabelRefUID: string(m.OBTenant.GetUID()), + }, client.InNamespace(m.OBTenant.Namespace)) + if err != nil { + return nil, errors.Wrap(err, "get obparameter list") + } + return obparameterList, nil +} + +func (m *OBTenantManager) generateParameterName(name string) string { + return fmt.Sprintf("%s-%s-%s", m.OBTenant.Spec.ClusterName, m.OBTenant.Name, strings.ReplaceAll(name, "_", "-")) +} + +func (m *OBTenantManager) createOBParameter(parameter *apitypes.Parameter) error { + m.Logger.Info("Create ob tenant parameters") + ownerReferenceList := make([]metav1.OwnerReference, 0) + ownerReference := metav1.OwnerReference{ + APIVersion: m.OBTenant.APIVersion, + Kind: m.OBTenant.Kind, + Name: m.OBTenant.Name, + UID: m.OBTenant.GetUID(), + } + ownerReferenceList = append(ownerReferenceList, ownerReference) + labels := make(map[string]string) + labels[oceanbaseconst.LabelRefUID] = string(m.OBTenant.GetUID()) + labels[oceanbaseconst.LabelRefOBTenant] = m.OBTenant.Name + parameterName := m.generateParameterName(parameter.Name) + obparameter := &v1alpha1.OBParameter{ + ObjectMeta: metav1.ObjectMeta{ + Name: parameterName, + Namespace: m.OBTenant.Namespace, + OwnerReferences: ownerReferenceList, + Labels: labels, + }, + Spec: v1alpha1.OBParameterSpec{ + ClusterName: m.OBTenant.Spec.ClusterName, + TenantName: m.OBTenant.Spec.TenantName, + TenantId: int64(m.OBTenant.Status.TenantRecordInfo.TenantID), + Parameter: parameter, + }, + } + m.Logger.V(oceanbaseconst.LogLevelDebug).Info("Create obparameter", "parameter", parameterName) + err := m.Client.Create(m.Ctx, obparameter) + if err != nil { + m.Logger.Error(err, "create obparameter failed") + return errors.Wrap(err, "create obparameter") + } + return nil +} + +func (m *OBTenantManager) updateOBParameter(parameter *apitypes.Parameter) error { + return retry.RetryOnConflict(retry.DefaultRetry, func() error { + obparameter := &v1alpha1.OBParameter{} + err := m.Client.Get(m.Ctx, types.NamespacedName{ + Namespace: m.OBTenant.Namespace, + Name: m.generateParameterName(parameter.Name), + }, obparameter) + if err != nil { + return errors.Wrap(err, "Get obparameter") + } + obparameter.Spec.Parameter.Value = parameter.Value + err = m.Client.Update(m.Ctx, obparameter) + if err != nil { + return errors.Wrap(err, "Update obparameter") + } + return nil + }) +} + +func (m *OBTenantManager) deleteOBParameter(parameter *apitypes.Parameter) error { + obparameter := &v1alpha1.OBParameter{} + err := m.Client.Get(m.Ctx, types.NamespacedName{ + Namespace: m.OBTenant.Namespace, + Name: m.generateParameterName(parameter.Name), + }, obparameter) + if err != nil { + return errors.Wrap(err, "Get obparameter") + } + obparameter.Spec.Parameter.Value = parameter.Value + err = m.Client.Delete(m.Ctx, obparameter) + if err != nil { + return errors.Wrap(err, "Delete obparameter") + } + return nil +} diff --git a/pkg/oceanbase-sdk/const/sql/parameter.go b/pkg/oceanbase-sdk/const/sql/parameter.go index 25d51b4e0..1df7c28af 100644 --- a/pkg/oceanbase-sdk/const/sql/parameter.go +++ b/pkg/oceanbase-sdk/const/sql/parameter.go @@ -15,8 +15,8 @@ package sql const ( SetParameter = "alter system set %s = ?" SetParameterWithScope = "alter system set %s = ? %s = ?" - QueryParameter = "select zone, svr_ip, svr_port, name, value, scope, edit_level from __all_virtual_sys_parameter_stat where name = ?" - QueryParameterWithScope = "select zone, svr_ip, svr_port, name, value, scope, edit_level from __all_virtual_sys_parameter_stat where name = ? and %s = ?" + QueryParameter = "select zone, svr_ip, svr_port, name, value, scope, edit_level, coalesce(tenant_id, 0) as tenant_id from gv$ob_parameters where name = ?" + QueryParameterWithScope = "select zone, svr_ip, svr_port, name, value, scope, edit_level, coalesce(tenant_id, 0) as tenant_id from gv$ob_parameters where name = ? and %s = ?" ) const (