Skip to content

Commit

Permalink
Fix panic issue in resource-metrics (#42)
Browse files Browse the repository at this point in the history
Signed-off-by: Arnob kumar saha <[email protected]>
  • Loading branch information
ArnobKumarSaha authored Apr 9, 2024
1 parent f0b12e0 commit f7b1661
Show file tree
Hide file tree
Showing 14 changed files with 537 additions and 12 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ require (
k8s.io/klog/v2 v2.120.1
kmodules.xyz/client-go v0.29.13
kmodules.xyz/custom-resources v0.29.1
kmodules.xyz/resource-metadata v0.18.2
kmodules.xyz/resource-metadata v0.18.3-0.20240409101929-fb5a9a4840c3
sigs.k8s.io/controller-runtime v0.17.2
)

Expand Down Expand Up @@ -117,7 +117,7 @@ require (
kmodules.xyz/apiversion v0.2.0 // indirect
kmodules.xyz/go-containerregistry v0.0.12 // indirect
kmodules.xyz/offshoot-api v0.29.0 // indirect
kmodules.xyz/resource-metrics v0.29.1 // indirect
kmodules.xyz/resource-metrics v0.29.5 // indirect
sigs.k8s.io/cli-utils v0.34.0 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -346,10 +346,10 @@ kmodules.xyz/go-containerregistry v0.0.12 h1:Tl32QGmSqRVm9PUEb/f3dgDeu9zW5fVzt3q
kmodules.xyz/go-containerregistry v0.0.12/go.mod h1:KgeNg0hDsgeda+qc0NzWk0iVRdF0+ZIg/oRzGoYh78I=
kmodules.xyz/offshoot-api v0.29.0 h1:GHLhxxT9jU1N8+FvOCCeJNyU5g0duYS46UGrs6AHNLY=
kmodules.xyz/offshoot-api v0.29.0/go.mod h1:5NxhBblXoDHWStx9HCDJR2KFTwYjEZ7i1Id3jelIunw=
kmodules.xyz/resource-metadata v0.18.2 h1:rfyq0Wnzx/2OiWGFbHTRp9cVvr2KI8xOCyy7gUVytm4=
kmodules.xyz/resource-metadata v0.18.2/go.mod h1:Vb2bFCOX4uz2TsRRMzTkUqFWWOjJ261lY8Hs2HWgzh4=
kmodules.xyz/resource-metrics v0.29.1 h1:gP4SNosdDGFImpne52mnQtHacmnllYkTMcYL//p/ltM=
kmodules.xyz/resource-metrics v0.29.1/go.mod h1:OuG/QobZ7o8GFHl/u3lqaUR0fDZDegxtV8Vdh+MNBD4=
kmodules.xyz/resource-metadata v0.18.3-0.20240409101929-fb5a9a4840c3 h1:J2tT40D8IseChz7ogjnR+C5m4f4ZjJuMrVrDxrREwOw=
kmodules.xyz/resource-metadata v0.18.3-0.20240409101929-fb5a9a4840c3/go.mod h1:feAzgq+5hSlmRKsLVMQz91H1QRjp25OMMQOztWF0lvQ=
kmodules.xyz/resource-metrics v0.29.5 h1:ciuvRXuXsloLNW/JwkubqbYySsvHvHr6/nhkTL5Sf1o=
kmodules.xyz/resource-metrics v0.29.5/go.mod h1:OuG/QobZ7o8GFHl/u3lqaUR0fDZDegxtV8Vdh+MNBD4=
sigs.k8s.io/cli-utils v0.34.0 h1:zCUitt54f0/MYj/ajVFnG6XSXMhpZ72O/3RewIchW8w=
sigs.k8s.io/cli-utils v0.34.0/go.mod h1:EXyMwPMu9OL+LRnj0JEMsGG/fRvbgFadcVlSnE8RhFs=
sigs.k8s.io/controller-runtime v0.17.2 h1:FwHwD1CTUemg0pW2otk7/U5/i5m2ymzvOXdbeGOUvw0=
Expand Down

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

5 changes: 3 additions & 2 deletions vendor/kmodules.xyz/resource-metadata/apis/shared/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ type RegistryInfo struct {
}

type HelmInfo struct {
Repositories map[string]*HelmRepository `json:"repositories"`
Releases map[string]*HelmRelease `json:"releases"`
CreateNamespace bool `json:"createNamespace"`
Repositories map[string]*HelmRepository `json:"repositories"`
Releases map[string]*HelmRelease `json:"releases"`
}

type HelmRepository struct {
Expand Down

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

3 changes: 3 additions & 0 deletions vendor/kmodules.xyz/resource-metrics/api/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,9 @@ func AppNodeResourcesV2(
}

dbContainer := GetContainerByName(node.PodTemplate.Spec.Containers, containerName)
if dbContainer == nil {
return nil, 0, fmt.Errorf("failed to find container %s in pod template", containerName)
}
rr := fn(dbContainer.Resources)
sr := fn(ToResourceRequirements(node.Storage.Resources))
rr[core.ResourceStorage] = *sr.Storage()
Expand Down
1 change: 1 addition & 0 deletions vendor/kmodules.xyz/resource-metrics/calculator.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
_ "kmodules.xyz/resource-metrics/batch/v1"
_ "kmodules.xyz/resource-metrics/batch/v1beta1"
_ "kmodules.xyz/resource-metrics/core/v1"
_ "kmodules.xyz/resource-metrics/kafka.kubedb.com/v1alpha1"
_ "kmodules.xyz/resource-metrics/kubedb.com/v1alpha2"
_ "kmodules.xyz/resource-metrics/kubevault.com/v1alpha2"
_ "kmodules.xyz/resource-metrics/ops.kubedb.com/v1alpha1"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
Copyright AppsCode Inc. and Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
"fmt"

core "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"kmodules.xyz/resource-metrics/api"
)

func init() {
api.Register(schema.GroupVersionKind{
Group: "kafka.kubedb.com",
Version: "v1alpha1",
Kind: "ConnectCluster",
}, ConnectCluster{}.ResourceCalculator())
}

type ConnectCluster struct{}

func (r ConnectCluster) ResourceCalculator() api.ResourceCalculator {
return &api.ResourceCalculatorFuncs{
AppRoles: []api.PodRole{api.PodRoleDefault},
RuntimeRoles: []api.PodRole{api.PodRoleDefault, api.PodRoleExporter},
RoleReplicasFn: r.roleReplicasFn,
ModeFn: r.modeFn,
UsesTLSFn: r.usesTLSFn,
RoleResourceLimitsFn: r.roleResourceFn(api.ResourceLimits),
RoleResourceRequestsFn: r.roleResourceFn(api.ResourceRequests),
}
}

func (r ConnectCluster) roleReplicasFn(obj map[string]interface{}) (api.ReplicaList, error) {
replicas, found, err := unstructured.NestedInt64(obj, "spec", "replicas")
if err != nil {
return nil, fmt.Errorf("failed to read spec.replicas %v: %w", obj, err)
}
if !found {
return api.ReplicaList{api.PodRoleDefault: 1}, nil
}
return api.ReplicaList{api.PodRoleDefault: replicas}, nil
}

func (r ConnectCluster) modeFn(obj map[string]interface{}) (string, error) {
replicas, _, err := unstructured.NestedInt64(obj, "spec", "replicas")
if err != nil {
return "", err
}
if replicas > 1 {
return ConnectClusterModeDistributed, nil
}
return ConnectClusterModeStandalone, nil
}

func (r ConnectCluster) usesTLSFn(obj map[string]interface{}) (bool, error) {
_, found, err := unstructured.NestedFieldNoCopy(obj, "spec", "enableSSL")
return found, err
}

func (r ConnectCluster) roleResourceFn(fn func(rr core.ResourceRequirements) core.ResourceList) func(obj map[string]interface{}) (map[api.PodRole]core.ResourceList, error) {
return func(obj map[string]interface{}) (map[api.PodRole]core.ResourceList, error) {
exporter, err := api.ContainerResources(obj, fn, "spec", "monitor", "prometheus", "exporter")
if err != nil {
return nil, err
}
container, replicas, err := api.AppNodeResourcesV2(obj, fn, ConnectClusterContainerName, "spec")
if err != nil {
return nil, err
}
return map[api.PodRole]core.ResourceList{
api.PodRoleDefault: api.MulResourceList(container, replicas),
api.PodRoleExporter: api.MulResourceList(exporter, replicas),
}, nil
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
Copyright AppsCode Inc. and Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

const (
ConnectClusterModeStandalone = "Standalone"
ConnectClusterModeDistributed = "Distributed"
)

const (
ConnectClusterContainerName = "connect-cluster"
)
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ const (
)

const (
DruidContainerName = "druid"
PgpoolContainerName = "pgpool"
RabbitMQContainerName = "rabbitmq"
SinglestoreContainerName = "singlestore"
SolrContainerName = "solr"
ZooKeeperContainerName = "zookeeper"
)
139 changes: 139 additions & 0 deletions vendor/kmodules.xyz/resource-metrics/kubedb.com/v1alpha2/druid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
Copyright AppsCode Inc. and Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha2

import (
"fmt"
"reflect"

"kmodules.xyz/resource-metrics/api"

core "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)

func init() {
api.Register(schema.GroupVersionKind{
Group: "kubedb.com",
Version: "v1alpha2",
Kind: "Druid",
}, Druid{}.ResourceCalculator())
}

type Druid struct{}

func (r Druid) ResourceCalculator() api.ResourceCalculator {
return &api.ResourceCalculatorFuncs{
AppRoles: []api.PodRole{api.PodRoleDefault},
RuntimeRoles: []api.PodRole{api.PodRoleDefault, api.PodRoleExporter},
RoleReplicasFn: r.roleReplicasFn,
ModeFn: r.modeFn,
UsesTLSFn: r.usesTLSFn,
RoleResourceLimitsFn: r.roleResourceFn(api.ResourceLimits),
RoleResourceRequestsFn: r.roleResourceFn(api.ResourceRequests),
}
}

func (r Druid) roleReplicasFn(obj map[string]interface{}) (api.ReplicaList, error) {
result := api.ReplicaList{}

topology, found, err := unstructured.NestedMap(obj, "spec", "topology")
if err != nil {
return nil, err
}

if found && topology != nil {
var replicas int64 = 0
for role, roleSpec := range topology {
roleReplicas, found, err := unstructured.NestedInt64(roleSpec.(map[string]interface{}), "replicas")
if err != nil {
return nil, err
}
if found {
result[api.PodRole(role)] = roleReplicas
replicas += roleReplicas
}
}
result[api.PodRoleDefault] = replicas
} else {
// Combined mode
replicas, found, err := unstructured.NestedInt64(obj, "spec", "replicas")
if err != nil {
return nil, fmt.Errorf("failed to read spec.replicas %v: %w", obj, err)
}
if !found {
result[api.PodRoleDefault] = 1
} else {
result[api.PodRoleDefault] = replicas
}
}

return result, nil
}

func (r Druid) modeFn(obj map[string]interface{}) (string, error) {
topology, found, err := unstructured.NestedFieldNoCopy(obj, "spec", "topology")
if err != nil {
return "", err
}
if found && !reflect.ValueOf(topology).IsNil() {
return DBModeDedicated, nil
}
return DBModeCombined, nil
}

func (r Druid) usesTLSFn(obj map[string]interface{}) (bool, error) {
_, found, err := unstructured.NestedFieldNoCopy(obj, "spec", "enableSSL")
return found, err
}

func (r Druid) roleResourceFn(fn func(rr core.ResourceRequirements) core.ResourceList) func(obj map[string]interface{}) (map[api.PodRole]core.ResourceList, error) {
return func(obj map[string]interface{}) (map[api.PodRole]core.ResourceList, error) {
exporter, err := api.ContainerResources(obj, fn, "spec", "monitor", "prometheus", "exporter")
if err != nil {
return nil, err
}

topology, found, err := unstructured.NestedMap(obj, "spec", "topology")
if err != nil {
return nil, err
}
if found && topology != nil {
var replicas int64 = 0
var totalResources core.ResourceList
result := map[api.PodRole]core.ResourceList{}

for role, roleSpec := range topology {
rolePerReplicaResources, roleReplicas, err := api.AppNodeResourcesV2(roleSpec.(map[string]interface{}), fn, DruidContainerName)
if err != nil {
return nil, err
}

roleResources := api.MulResourceList(rolePerReplicaResources, roleReplicas)
result[api.PodRole(role)] = roleResources
totalResources = api.AddResourceList(totalResources, roleResources)
}

result[api.PodRoleDefault] = totalResources
result[api.PodRoleExporter] = api.MulResourceList(exporter, replicas)
return result, nil
}

return nil, nil
}
}
Loading

0 comments on commit f7b1661

Please sign in to comment.