Skip to content

Commit

Permalink
[release-4.9] OCPBUGS-443 Gather status of the cephclusters.ceph.rook…
Browse files Browse the repository at this point in the history
….io resources (#659)
  • Loading branch information
tremes committed Aug 23, 2022
1 parent 21096da commit 8709611
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 2 deletions.
14 changes: 14 additions & 0 deletions docs/gathered-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ The CRD sizes above are in the raw (uncompressed) state.
* Id in config: crds


## CephCluster

collects statuses of the`cephclusters.ceph.rook.io` resources
from Openshift Data Foundation Stack.

API Reference:
https://github.com/rook/rook/blob/master/pkg/apis/ceph.rook.io/v1/types.go

* Location in archive: config/storage/<namespace>/<name>.json
* Id in config: clusterconfig/ceph_cluster
* Since versions:
* 4.12+


## CertificateSigningRequests

collects anonymized CertificateSigningRequests.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"ceph": {
"capacity": {},
"details": {
"MDS_ALL_DOWN": {
"message": "1 filesystem is offline",
"severity": "HEALTH_ERR"
},
"MDS_UP_LESS_THAN_MAX": {
"message": "1 filesystem is online with fewer MDS than max_mds",
"severity": "HEALTH_WARN"
},
"MGR_DOWN": {
"message": "no active mgr",
"severity": "HEALTH_WARN"
}
},
"health": "HEALTH_ERR",
"lastChanged": "2022-07-18T13:43:24Z",
"lastChecked": "2022-07-19T07:29:56Z",
"previousHealth": "HEALTH_WARN",
"versions": {
"mon": {
"ceph version 16.2.7-112.el8cp (e18db2ff03ac60c64a18f3315c032b9d5a0a3b8f) pacific (stable)": 3
},
"overall": {
"ceph version 16.2.7-112.el8cp (e18db2ff03ac60c64a18f3315c032b9d5a0a3b8f) pacific (stable)": 3
}
}
},
"conditions": [
{
"lastHeartbeatTime": "2022-07-19T07:29:56Z",
"lastTransitionTime": "2022-07-18T13:42:23Z",
"message": "Cluster created successfully",
"reason": "ClusterCreated",
"status": "True",
"type": "Ready"
}
],
"message": "Cluster created successfully",
"phase": "Ready",
"state": "Created",
"version": {
"image": "registry.redhat.io/rhceph/rhceph-5-rhel8@sha256:b20a05e20403da9775408fde0f10ba9c81c5610a3814db7786dd43ce4b2aba4a",
"version": "16.2.7-112"
}
}
10 changes: 8 additions & 2 deletions manifests/03-clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,14 @@ rules:
verbs:
- get
- list
- watch

- watch
- apiGroups:
- ceph.rook.io
resources:
- cephclusters
verbs:
- get
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
Expand Down
54 changes: 54 additions & 0 deletions pkg/gatherers/clusterconfig/ceph_cluster.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//nolint: dupl
package clusterconfig

import (
"context"
"fmt"

"github.com/openshift/insights-operator/pkg/record"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/dynamic"
"k8s.io/klog/v2"
)

// GatherCephCluster collects statuses of the`cephclusters.ceph.rook.io` resources
// from Openshift Data Foundation Stack.
//
// API Reference:
// https://github.com/rook/rook/blob/master/pkg/apis/ceph.rook.io/v1/types.go
//
// * Location in archive: config/storage/<namespace>/<name>.json
// * Id in config: clusterconfig/ceph_cluster
// * Since versions:
// * 4.12+
func (g *Gatherer) GatherCephCluster(ctx context.Context) ([]record.Record, []error) {
gatherDynamicClient, err := dynamic.NewForConfig(g.gatherKubeConfig)
if err != nil {
return nil, []error{err}
}

return gatherCephCluster(ctx, gatherDynamicClient)
}

func gatherCephCluster(ctx context.Context, dynamicClient dynamic.Interface) ([]record.Record, []error) {
cephClusterList, err := dynamicClient.Resource(cephClustereResource).List(ctx, metav1.ListOptions{})
if errors.IsNotFound(err) {
return nil, nil
}
if err != nil {
klog.V(2).Infof("Unable to list %s resource due to: %s", gatherCephCluster, err)
return nil, []error{err}
}

var records []record.Record
for i := range cephClusterList.Items {
item := &cephClusterList.Items[i]
status := item.Object["status"]
records = append(records, record.Record{
Name: fmt.Sprintf("config/storage/%s/%s", item.GetNamespace(), item.GetName()),
Item: record.JSONMarshaller{Object: status},
})
}
return records, nil
}
68 changes: 68 additions & 0 deletions pkg/gatherers/clusterconfig/ceph_cluster_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package clusterconfig

import (
"context"
"encoding/json"
"testing"

"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/yaml"
dynamicfake "k8s.io/client-go/dynamic/fake"
)

func Test_GatherCephCluster(t *testing.T) {
var cephClusterYAML = `
apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
name: ocs-storagecluster-cephcluster
namespace: openshift-storage
status:
attribute1: value1
ceph:
phase: Ready
health: HEALTH_ERROR
`

dynamicClient := dynamicfake.NewSimpleDynamicClientWithCustomListKinds(runtime.NewScheme(), map[schema.GroupVersionResource]string{
cephClustereResource: "CephClustersList",
})
decUnstructured := yaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme)
testCephCluster := &unstructured.Unstructured{}

_, _, err := decUnstructured.Decode([]byte(cephClusterYAML), nil, testCephCluster)
if err != nil {
t.Fatal("unable to decode cephcluster ", err)
}
_, err = dynamicClient.Resource(cephClustereResource).
Namespace("openshift-storage").
Create(context.Background(), testCephCluster, metav1.CreateOptions{})
if err != nil {
t.Fatal("unable to create fake cephcluster ", err)
}

records, errs := gatherCephCluster(context.Background(), dynamicClient)
assert.Len(t, errs, 0, "unexpected errors when gathering CephCluster resource")
assert.Len(t, records, 1)

recordData, err := records[0].Item.Marshal(context.Background())
assert.NoError(t, err)
var recordedCephCluster map[string]interface{}
err = json.Unmarshal(recordData, &recordedCephCluster)
assert.NoError(t, err)

a1, ok, err := unstructured.NestedString(recordedCephCluster, "attribute1")
assert.NoError(t, err)
assert.True(t, ok)
assert.Equal(t, "value1", a1)

ceph, ok, err := unstructured.NestedMap(recordedCephCluster, "ceph")
assert.NoError(t, err)
assert.True(t, ok)
assert.Equal(t, "Ready", ceph["phase"])
assert.Equal(t, "HEALTH_ERROR", ceph["health"])
}
1 change: 1 addition & 0 deletions pkg/gatherers/clusterconfig/clusterconfig_gatherer.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ var gatheringFunctions = map[string]gatheringFunction{
"cost_management_metrics_configs": failableFunc((*Gatherer).GatherCostManagementMetricsConfigs),
"kube_controller_manager_logs": failableFunc((*Gatherer).GatherKubeControllerManagerLogs),
"overlapping_namespace_uids": failableFunc((*Gatherer).GatherNamespacesWithOverlappingUIDs),
"ceph_cluster": failableFunc((*Gatherer).GatherCephCluster),
}

func New(
Expand Down
3 changes: 3 additions & 0 deletions pkg/gatherers/clusterconfig/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ var (
openshiftLoggingResource = schema.GroupVersionResource{
Group: "logging.openshift.io", Version: "v1", Resource: "clusterloggings",
}
cephClustereResource = schema.GroupVersionResource{
Group: "ceph.rook.io", Version: "v1", Resource: "cephclusters",
}
costManagementMetricsConfigResource = schema.GroupVersionResource{
Group: "costmanagement-metrics-cfg.openshift.io", Version: "v1beta1", Resource: "costmanagementmetricsconfigs",
}
Expand Down

0 comments on commit 8709611

Please sign in to comment.