From 6b6efc3d138d7af80519caea5a5f7487329993ba Mon Sep 17 00:00:00 2001 From: Raul Sevilla Date: Tue, 21 Nov 2023 23:53:14 +0100 Subject: [PATCH 1/2] New function to get k8s metadata Signed-off-by: Raul Sevilla --- ocp-metadata/ocp-metadata.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ocp-metadata/ocp-metadata.go b/ocp-metadata/ocp-metadata.go index 0f8254b..883ef3c 100644 --- a/ocp-metadata/ocp-metadata.go +++ b/ocp-metadata/ocp-metadata.go @@ -79,6 +79,19 @@ func (meta *Metadata) GetClusterMetadata() (ClusterMetadata, error) { return metadata, err } +func (meta *Metadata) GetK8SMetadata() (ClusterMetadata, error) { + metadata := ClusterMetadata{} + version, err := meta.clientSet.ServerVersion() + if err != nil { + return metadata, err + } + metadata.K8SVersion = version.GitVersion + if meta.getNodesInfo(&metadata) != nil { + return metadata, err + } + return metadata, err +} + // GetPrometheus Returns Prometheus URL and a valid Bearer token func (meta *Metadata) GetPrometheus() (string, string, error) { prometheusURL, err := getPrometheusURL(meta.dynamicClient) From 7840ef71ad9239577bb022361ed5ef8dca55bb97 Mon Sep 17 00:00:00 2001 From: Raul Sevilla Date: Wed, 22 Nov 2023 00:13:08 +0100 Subject: [PATCH 2/2] Count control-plane labeled nodes as masters and omit empty fields when marshalling JSON Signed-off-by: Raul Sevilla --- ocp-metadata/ocp-metadata.go | 58 ++++++++++++++++++------------------ ocp-metadata/types.go | 32 ++++++++++---------- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/ocp-metadata/ocp-metadata.go b/ocp-metadata/ocp-metadata.go index 883ef3c..4424b2e 100644 --- a/ocp-metadata/ocp-metadata.go +++ b/ocp-metadata/ocp-metadata.go @@ -21,6 +21,7 @@ import ( "regexp" authenticationv1 "k8s.io/api/authentication/v1" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -57,16 +58,18 @@ func (meta *Metadata) GetClusterMetadata() (ClusterMetadata, error) { if err != nil { return metadata, nil } - metadata.ClusterName, metadata.Platform, metadata.Region = infra.Status.InfrastructureName, infra.Status.Platform, infra.Status.PlatformStatus.Aws.Region - metadata.ClusterType = "self-managed" - for _, v := range infra.Status.PlatformStatus.Aws.ResourceTags { - if v.Key == "red-hat-clustertype" { - metadata.ClusterType = v.Value + if infra != nil { + metadata.ClusterName, metadata.Platform, metadata.Region = infra.Status.InfrastructureName, infra.Status.Platform, infra.Status.PlatformStatus.Aws.Region + metadata.ClusterType = "self-managed" + for _, v := range infra.Status.PlatformStatus.Aws.ResourceTags { + if v.Key == "red-hat-clustertype" { + metadata.ClusterType = v.Value + } + } + metadata.SDNType, err = meta.getSDNInfo() + if err != nil { + return metadata, err } - } - metadata.SDNType, err = meta.getSDNInfo() - if err != nil { - return metadata, err } version, err := meta.getVersionInfo() if err != nil { @@ -79,19 +82,6 @@ func (meta *Metadata) GetClusterMetadata() (ClusterMetadata, error) { return metadata, err } -func (meta *Metadata) GetK8SMetadata() (ClusterMetadata, error) { - metadata := ClusterMetadata{} - version, err := meta.clientSet.ServerVersion() - if err != nil { - return metadata, err - } - metadata.K8SVersion = version.GitVersion - if meta.getNodesInfo(&metadata) != nil { - return metadata, err - } - return metadata, err -} - // GetPrometheus Returns Prometheus URL and a valid Bearer token func (meta *Metadata) GetPrometheus() (string, string, error) { prometheusURL, err := getPrometheusURL(meta.dynamicClient) @@ -167,8 +157,8 @@ func getBearerToken(clientset *kubernetes.Clientset) (string, error) { return response.Status.Token, err } -// getInfraDetails returns cluster name and platform -func (meta *Metadata) getInfraDetails() (infraObj, error) { +// getInfraDetails returns a pointer to an infrastructure object or nil +func (meta *Metadata) getInfraDetails() (*infraObj, error) { var infraJSON infraObj infra, err := meta.dynamicClient.Resource(schema.GroupVersionResource{ Group: "config.openshift.io", @@ -176,11 +166,15 @@ func (meta *Metadata) getInfraDetails() (infraObj, error) { Resource: "infrastructures", }).Get(context.TODO(), "cluster", metav1.GetOptions{}) if err != nil { - return infraJSON, err + // If the infrastructure resource is not found we assume this is not an OCP cluster + if errors.IsNotFound(err) { + return nil, nil + } + return &infraJSON, err } infraData, _ := infra.MarshalJSON() err = json.Unmarshal(infraData, &infraJSON) - return infraJSON, err + return &infraJSON, err } // getVersionInfo obtains OCP and k8s version information @@ -199,6 +193,10 @@ func (meta *Metadata) getVersionInfo() (versionObj, error) { Resource: "clusterversions", }).Get(context.TODO(), "version", metav1.GetOptions{}) if err != nil { + // If the clusterversion resource is not found we assume this is not an OCP cluster + if errors.IsNotFound(err) { + return versionInfo, nil + } return versionInfo, err } clusterVersionBytes, _ := clusterVersion.MarshalJSON() @@ -225,17 +223,19 @@ func (meta *Metadata) getNodesInfo(clusterMetadata *ClusterMetadata) error { return err } clusterMetadata.TotalNodes = len(nodes.Items) - // When the master label is found, the node is considered a master, regarldess of other labels the node could have - // similar logic happens with the infra nodes + // When the master label is found, the node is considered a master, regardless of other labels the node could have for _, node := range nodes.Items { if _, ok := node.Labels["node-role.kubernetes.io/master"]; ok { // Check for master role clusterMetadata.MasterNodesCount++ clusterMetadata.MasterNodesType = node.Labels["node.kubernetes.io/instance-type"] if _, ok := node.Labels["node-role.kubernetes.io/worker"]; ok { - if len(node.Spec.Taints) == 0 { // When mastersSchedulable is true, master nodes have at least one taint + if len(node.Spec.Taints) == 0 { // When mastersSchedulable is false, master nodes have at least one taint clusterMetadata.WorkerNodesCount++ } } + } else if _, ok := node.Labels["node-role.kubernetes.io/control-plane"]; ok { // Check for control-plane role + clusterMetadata.MasterNodesCount++ + clusterMetadata.MasterNodesType = node.Labels["node.kubernetes.io/instance-type"] } else if _, ok := node.Labels["node-role.kubernetes.io/infra"]; ok { // Check for infra role clusterMetadata.InfraNodesCount++ clusterMetadata.InfraNodesType = node.Labels["node.kubernetes.io/instance-type"] diff --git a/ocp-metadata/types.go b/ocp-metadata/types.go index 50f231e..42eab27 100644 --- a/ocp-metadata/types.go +++ b/ocp-metadata/types.go @@ -71,20 +71,20 @@ type clusterVersion struct { // Type to store cluster metadata type ClusterMetadata struct { MetricName string `json:"metricName,omitempty"` - Platform string `json:"platform"` - ClusterType string `json:"clusterType"` - OCPVersion string `json:"ocpVersion"` - OCPMajorVersion string `json:"ocpMajorVersion"` - K8SVersion string `json:"k8sVersion"` - MasterNodesType string `json:"masterNodesType"` - WorkerNodesType string `json:"workerNodesType"` - MasterNodesCount int `json:"masterNodesCount"` - InfraNodesType string `json:"infraNodesType"` - WorkerNodesCount int `json:"workerNodesCount"` - InfraNodesCount int `json:"infraNodesCount"` - OtherNodesCount int `json:"otherNodesCount"` - TotalNodes int `json:"totalNodes"` - SDNType string `json:"sdnType"` - ClusterName string `json:"clusterName"` - Region string `json:"region"` + Platform string `json:"platform,omitempty"` + ClusterType string `json:"clusterType,omitempty"` + OCPVersion string `json:"ocpVersion,omitempty"` + OCPMajorVersion string `json:"ocpMajorVersion,omitempty"` + K8SVersion string `json:"k8sVersion,omitempty"` + MasterNodesType string `json:"masterNodesType,omitempty"` + WorkerNodesType string `json:"workerNodesType,omitempty"` + MasterNodesCount int `json:"masterNodesCount,omitempty"` + InfraNodesType string `json:"infraNodesType,omitempty"` + WorkerNodesCount int `json:"workerNodesCount,omitempty"` + InfraNodesCount int `json:"infraNodesCount,omitempty"` + OtherNodesCount int `json:"otherNodesCount,omitempty"` + TotalNodes int `json:"totalNodes,omitempty"` + SDNType string `json:"sdnType,omitempty"` + ClusterName string `json:"clusterName,omitempty"` + Region string `json:"region,omitempty"` }