Skip to content

Commit c71e2ed

Browse files
committed
Merge branch 'master' of github.com:oceanbase/ob-operator into wt-ds040-nodeBugfix
2 parents 28e3b99 + 0a3edd8 commit c71e2ed

File tree

32 files changed

+434
-140
lines changed

32 files changed

+434
-140
lines changed

build/Dockerfile.dashboard

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ RUN yarn
66
RUN yarn build
77

88
FROM golang:1.22 AS builder-be
9-
ARG GOPROXY=https://goproxy.cn,direct
9+
ARG GOPROXY=https://goproxy.io,direct
1010
ARG GOSUMDB=sum.golang.org
1111
ARG COMMIT_HASH=unknown
1212
WORKDIR /workspace
@@ -16,10 +16,10 @@ RUN make dashboard-build
1616
# start build docker image
1717
FROM openanolis/anolisos:8.8
1818
WORKDIR /root
19+
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
20+
RUN yum update -y && yum install -y mysql && yum clean all
1921
COPY --from=builder-be /workspace/bin/oceanbase-dashboard .
2022
COPY --from=builder-fe /workspace/dist ./ui/dist
21-
RUN yum update -y && yum install -y mysql && yum clean all
22-
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2323
USER root
2424

2525
ENTRYPOINT ["/root/oceanbase-dashboard"]

charts/oceanbase-dashboard/templates/cluster-role.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ rules:
1212
resources:
1313
- "*"
1414
verbs: ["get", "list", "watch", "update", "create", "delete", "patch"]
15+
- apiGroups:
16+
- k8s.oceanbase.com
17+
resources:
18+
- "*"
19+
verbs: ["get", "list", "watch", "update", "create", "delete", "patch"]
1520
- apiGroups:
1621
- ""
1722
resources:

internal/clients/obcluster.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,19 @@ func GetPodOfOBServer(ctx context.Context, observer *v1alpha1.OBServer) (*corev1
170170
}
171171
return pod, nil
172172
}
173+
174+
func ListOBParametersOfOBCluster(ctx context.Context, obcluster *v1alpha1.OBCluster) (*v1alpha1.OBParameterList, error) {
175+
client := client.GetClient()
176+
var obparameterList v1alpha1.OBParameterList
177+
obj, err := client.DynamicClient.Resource(schema.OBParameterGVR).Namespace(obcluster.Namespace).List(ctx, metav1.ListOptions{
178+
LabelSelector: fmt.Sprintf("%s=%s", oceanbaseconst.LabelRefUID, string(obcluster.GetUID())),
179+
})
180+
if err != nil {
181+
return nil, errors.Wrap(err, "List obparameters")
182+
}
183+
err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), &obparameterList)
184+
if err != nil {
185+
return nil, errors.Wrap(err, "Convert unstructured to obparameter list")
186+
}
187+
return &obparameterList, nil
188+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
Copyright (c) 2025 OceanBase
3+
ob-operator is licensed under Mulan PSL v2.
4+
You can use this software according to the terms and conditions of the Mulan PSL v2.
5+
You may obtain a copy of Mulan PSL v2 at:
6+
http://license.coscl.org.cn/MulanPSL2
7+
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8+
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9+
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10+
See the Mulan PSL v2 for more details.
11+
*/
12+
13+
package schema
14+
15+
import "k8s.io/apimachinery/pkg/runtime/schema"
16+
17+
const (
18+
OBParameterGroup = "oceanbase.oceanbase.com"
19+
OBParameterVersion = "v1alpha1"
20+
OBParameterKind = "OBParameter"
21+
OBParameterResource = "obparameters"
22+
)
23+
24+
var (
25+
OBParameterGVR = schema.GroupVersionResource{
26+
Group: OBParameterGroup,
27+
Version: OBParameterVersion,
28+
Resource: OBParameterResource,
29+
}
30+
)

internal/dashboard/business/k8s/utils.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ func GetClientForK8sCluster(ctx context.Context, clusterName string) (*client.Cl
3838
if err != nil {
3939
return nil, errors.Wrap(err, "Get k8s cluster")
4040
}
41-
return client.GetClientFromBytes([]byte(k8sCluster.Spec.KubeConfig))
41+
kubeConfig, err := k8sCluster.DecodeKubeConfig()
42+
if err != nil {
43+
return nil, errors.Wrap(err, "Decode kubeconfig")
44+
}
45+
return client.GetClientFromBytes(kubeConfig)
4246
}
4347

4448
func ListK8sClusterEvents(ctx context.Context, c *client.Client, queryEventParam *param.QueryEventParam) ([]response.K8sEvent, error) {
@@ -127,7 +131,7 @@ func ListK8sClusterEvents(ctx context.Context, c *client.Client, queryEventParam
127131
func ListK8sClusterNodes(ctx context.Context, c *client.Client) ([]response.K8sNode, error) {
128132
nodeList, err := c.ClientSet.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
129133
nodes := make([]response.K8sNode, 0)
130-
nodeMetricsMap, metricsErr := resource.ListNodeMetrics(ctx)
134+
nodeMetricsMap, metricsErr := resource.ListNodeMetrics(ctx, c)
131135
if err == nil {
132136
for _, node := range nodeList.Items {
133137
internalAddress, externalAddress := extractNodeAddress(&node)
@@ -232,3 +236,7 @@ func BatchUpdateK8sClusterNodes(ctx context.Context, c *client.Client, updateNod
232236
}
233237
return nil
234238
}
239+
240+
func GetPod(ctx context.Context, c *client.Client, namespace string, name string) (*corev1.Pod, error) {
241+
return c.ClientSet.CoreV1().Pods(namespace).Get(ctx, name, metav1.GetOptions{})
242+
}

internal/dashboard/business/oceanbase/obcluster.go

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ import (
3333
clusterstatus "github.com/oceanbase/ob-operator/internal/const/status/obcluster"
3434
"github.com/oceanbase/ob-operator/internal/dashboard/business/common"
3535
"github.com/oceanbase/ob-operator/internal/dashboard/business/constant"
36+
"github.com/oceanbase/ob-operator/internal/dashboard/business/k8s"
3637
modelcommon "github.com/oceanbase/ob-operator/internal/dashboard/model/common"
3738
"github.com/oceanbase/ob-operator/internal/dashboard/model/param"
3839
"github.com/oceanbase/ob-operator/internal/dashboard/model/response"
3940
"github.com/oceanbase/ob-operator/internal/dashboard/utils"
4041
oberr "github.com/oceanbase/ob-operator/pkg/errors"
42+
"github.com/oceanbase/ob-operator/pkg/k8s/client"
4143
"github.com/oceanbase/ob-operator/pkg/oceanbase-sdk/model"
4244
)
4345

@@ -122,17 +124,19 @@ func buildOBClusterResponse(ctx context.Context, obcluster *v1alpha1.OBCluster)
122124
logger.WithError(err).Info("Failed to get OceanBase database connection")
123125
return nil, errors.Wrapf(err, "Failed to get connection of obcluster")
124126
}
127+
versionStr := ""
125128
version, err := conn.GetVersion(ctx)
126129
if err != nil {
127130
logger.WithError(err).Info("Failed to get OceanBase database version")
128-
return nil, errors.Wrapf(err, "Failed to get version of obcluster")
131+
} else {
132+
versionStr = version.Version
129133
}
130134

131135
respCluster := &response.OBCluster{
132136
OBClusterOverview: *overview,
133137
OBClusterExtra: response.OBClusterExtra{
134138
RootPasswordSecret: obcluster.Spec.UserSecrets.Root,
135-
Version: version.Version,
139+
Version: versionStr,
136140
Parameters: nil,
137141
},
138142
Metrics: nil,
@@ -216,13 +220,21 @@ func buildOBClusterTopologyResp(ctx context.Context, obcluster *v1alpha1.OBClust
216220
sort.Slice(observerList.Items, func(i, j int) bool {
217221
return observerList.Items[i].Name < observerList.Items[j].Name
218222
})
223+
c := client.GetClient()
224+
if obzone.Spec.Topology.K8sCluster != "" {
225+
c, err = k8s.GetClientForK8sCluster(ctx, obzone.Spec.Topology.K8sCluster)
226+
if err != nil {
227+
return nil, errors.Wrap(err, fmt.Sprintf("Get client for k8s cluster %s", obzone.Spec.Topology.K8sCluster))
228+
}
229+
}
219230
for _, observer := range observerList.Items {
220231
logger.Debugf("Add observer %s to result", observer.Name)
221232
// compatible with old version CRD
222233
nodeName := observer.Status.NodeName
223234
if nodeName == "" {
224235
logger.Debugf("Get node name of observer %s", observer.Name)
225-
pod, err := clients.GetPodOfOBServer(ctx, &observer)
236+
// pod name is the same as observer's name
237+
pod, err := k8s.GetPod(ctx, c, observer.Namespace, observer.Name)
226238
if err == nil {
227239
nodeName = pod.Spec.NodeName
228240
}
@@ -370,7 +382,7 @@ func buildOBClusterTopologyResp(ctx context.Context, obcluster *v1alpha1.OBClust
370382
Tolerations: tolerations,
371383
}
372384
if len(obzone.Status.OBServerStatus) > 0 {
373-
respZone.RootService = obzone.Status.OBServerStatus[0].Server
385+
respZone.RootService = obzone.Status.OBServerStatus[0].GetConnectAddr()
374386
}
375387
topology = append(topology, respZone)
376388
}
@@ -467,6 +479,7 @@ func buildOBClusterTopology(topology []param.ZoneTopology) []apitypes.OBZoneTopo
467479
Zone: zone.Zone,
468480
NodeSelector: common.KVsToMap(zone.NodeSelector),
469481
Replica: zone.Replicas,
482+
K8sCluster: zone.K8sCluster,
470483
}
471484
if len(zone.Affinities) > 0 {
472485
topo.Affinity = &corev1.Affinity{}
@@ -742,6 +755,7 @@ func AddOBZone(ctx context.Context, obclusterIdentity *param.K8sObjectIdentity,
742755
Zone: zone.Zone,
743756
NodeSelector: common.KVsToMap(zone.NodeSelector),
744757
Replica: zone.Replicas,
758+
K8sCluster: zone.K8sCluster,
745759
})
746760
cluster, err := clients.UpdateOBCluster(ctx, obcluster)
747761
if err != nil {
@@ -967,13 +981,18 @@ func ListOBClusterParameters(ctx context.Context, nn *param.K8sObjectIdentity) (
967981
logger.WithError(err).Info("Failed to get OceanBase database connection")
968982
return nil, errors.Wrapf(err, "Failed to get connection go obcluster")
969983
}
984+
parameterList, err := clients.ListOBParametersOfOBCluster(ctx, obcluster)
985+
if err != nil {
986+
logger.WithError(err).Error("Failed to list parameters")
987+
return nil, errors.New("Failed to list obcluster parameters in k8s")
988+
}
970989
parameters, err := conn.ListClusterParameters(ctx)
971990
if err != nil {
972991
logger.WithError(err).Error("Failed to query parameters")
973-
return nil, errors.New("Failed to list obcluster parameters")
992+
return nil, errors.New("Failed to list obcluster parameters in obcluster")
974993
}
975994
// convert to response data structure
976-
aggParameters := aggregrateParametersByName(parameters)
995+
aggParameters := aggregrateParameters(parameterList.Items, parameters)
977996
return aggParameters, nil
978997
}
979998

@@ -1033,7 +1052,7 @@ func aggregrateParameterByName(parameters []*model.Parameter) response.Aggregate
10331052
}
10341053
}
10351054

1036-
func aggregrateParametersByName(parameters []*model.Parameter) []response.AggregatedParameter {
1055+
func aggregrateParameters(obparameters []v1alpha1.OBParameter, parameters []*model.Parameter) []response.AggregatedParameter {
10371056
aggMap := make(map[string][]*model.Parameter)
10381057
for _, parameter := range parameters {
10391058
parameterList, exists := aggMap[parameter.Name]
@@ -1044,8 +1063,15 @@ func aggregrateParametersByName(parameters []*model.Parameter) []response.Aggreg
10441063
aggMap[parameter.Name] = parameterList
10451064
}
10461065
aggParameters := make([]response.AggregatedParameter, 0)
1047-
for _, parameterList := range aggMap {
1066+
for name, parameterList := range aggMap {
10481067
aggParameter := aggregrateParameterByName(parameterList)
1068+
for _, obparameter := range obparameters {
1069+
if name == obparameter.Spec.Parameter.Name {
1070+
aggParameter.IsManagedByOperator = true
1071+
aggParameter.Status = obparameter.Status.Status
1072+
break
1073+
}
1074+
}
10491075
aggParameters = append(aggParameters, aggParameter)
10501076
}
10511077
return aggParameters

internal/dashboard/business/oceanbase/obtenant.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ func CreateOBTenant(ctx context.Context, nn types.NamespacedName, p *param.Creat
289289

290290
// use password from root credential
291291
if p.RootCredential != "" {
292-
rootSecret, err := k8sclient.ClientSet.CoreV1().Secrets(t.Namespace).Get(ctx, p.RootCredential, v1.GetOptions{})
292+
rootSecret, err := k8sclient.ClientSet.CoreV1().Secrets(p.SecretNamespace).Get(ctx, p.RootCredential, v1.GetOptions{})
293293
if err != nil {
294294
return nil, oberr.NewInternal(err.Error())
295295
}
@@ -384,7 +384,7 @@ func CreateOBTenant(ctx context.Context, nn types.NamespacedName, p *param.Creat
384384
if p.Source != nil && p.Source.Restore != nil {
385385
// extract BakEncryptionPassword and OSS ak/sk
386386
if p.Source.Restore.BakEncryptionSecret != "" {
387-
bakEncryptionSecret, err := k8sclient.ClientSet.CoreV1().Secrets(t.Namespace).Get(ctx, p.Source.Restore.BakEncryptionSecret, v1.GetOptions{})
387+
bakEncryptionSecret, err := k8sclient.ClientSet.CoreV1().Secrets(p.SecretNamespace).Get(ctx, p.Source.Restore.BakEncryptionSecret, v1.GetOptions{})
388388
if err != nil {
389389
return nil, oberr.NewInternal(err.Error())
390390
}
@@ -393,7 +393,7 @@ func CreateOBTenant(ctx context.Context, nn types.NamespacedName, p *param.Creat
393393
}
394394
}
395395
if p.Source.Restore.OSSAccessSecret != "" {
396-
ossAccessSecret, err := k8sclient.ClientSet.CoreV1().Secrets(t.Namespace).Get(ctx, p.Source.Restore.OSSAccessSecret, v1.GetOptions{})
396+
ossAccessSecret, err := k8sclient.ClientSet.CoreV1().Secrets(p.SecretNamespace).Get(ctx, p.Source.Restore.OSSAccessSecret, v1.GetOptions{})
397397
if err != nil {
398398
return nil, oberr.NewInternal(err.Error())
399399
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
Copyright (c) 2025 OceanBase
3+
ob-operator is licensed under Mulan PSL v2.
4+
You can use this software according to the terms and conditions of the Mulan PSL v2.
5+
You may obtain a copy of Mulan PSL v2 at:
6+
http://license.coscl.org.cn/MulanPSL2
7+
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8+
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9+
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10+
See the Mulan PSL v2 for more details.
11+
*/
12+
13+
package handler
14+
15+
const (
16+
HEADER_ENCRYPTED_KEY string = "X-Encrypted-Key"
17+
)

internal/dashboard/handler/helper.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ func extractPassword(param *param.CreateOBClusterParam) error {
112112
if err != nil {
113113
return err
114114
}
115-
param.ProxyroPassword, err = crypto.DecryptWithPrivateKey(param.ProxyroPassword)
115+
if param.ProxyroPassword != "" {
116+
param.ProxyroPassword, err = crypto.DecryptWithPrivateKey(param.ProxyroPassword)
117+
}
116118
return err
117119
}

internal/dashboard/handler/obtenant_handler.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ func CreateTenant(c *gin.Context) (*response.OBTenantDetail, error) {
150150
return nil, httpErr.New(httpErr.ErrPermissionDenied, "Permission denied")
151151
}
152152

153+
if tenantParam.SecretNamespace == "" {
154+
tenantParam.SecretNamespace = "default"
155+
}
153156
if tenantParam.RootPassword != "" {
154157
tenantParam.RootPassword, err = crypto.DecryptWithPrivateKey(tenantParam.RootPassword)
155158
if err != nil {

0 commit comments

Comments
 (0)