github.com/verrazzano/verrazzano@v1.7.1/tools/vz/pkg/internal/util/cluster/clusterapi/ociclusters.go (about)

     1  // Copyright (c) 2023, 2024, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package clusterapi
     5  
     6  import (
     7  	"fmt"
     8  	"path/filepath"
     9  
    10  	"github.com/verrazzano/verrazzano/tools/vz/pkg/internal/util/files"
    11  	"github.com/verrazzano/verrazzano/tools/vz/pkg/internal/util/report"
    12  	corev1 "k8s.io/api/core/v1"
    13  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    14  )
    15  
    16  const ociClustersResource = "ociclusters.infrastructure.cluster.x-k8s.io"
    17  
    18  // Minimal definition of ociclusters.infrastructure.cluster.x-k8s.io object that only contains the fields that
    19  // will be analyzed.
    20  type ociClusterList struct {
    21  	metav1.TypeMeta `json:",inline"`
    22  	metav1.ListMeta `json:"metadata,omitempty"`
    23  	Items           []ociCluster `json:"items"`
    24  }
    25  type ociCluster struct {
    26  	metav1.TypeMeta   `json:",inline"`
    27  	metav1.ObjectMeta `json:"metadata,omitempty"`
    28  	Status            ociClusterStatus `json:"status,omitempty"`
    29  }
    30  type ociClusterStatus struct {
    31  	Conditions []capiCondition `json:"conditions,omitempty"`
    32  	Ready      bool            `json:"ready,omitempty"`
    33  }
    34  
    35  // AnalyzeOCIClusters handles the checking of the status of cluster-api ocicluster resources.
    36  func AnalyzeOCIClusters(clusterRoot string, namespace string, issueReporter *report.IssueReporter) error {
    37  	resourceRoot := clusterRoot
    38  	if len(namespace) != 0 {
    39  		resourceRoot = filepath.Join(clusterRoot, namespace)
    40  	}
    41  	list := &ociClusterList{}
    42  	err := files.UnmarshallFileInClusterRoot(resourceRoot, "ocicluster.infrastructure.cluster.x-k8s.io.json", list)
    43  	if err != nil {
    44  		return err
    45  	}
    46  
    47  	for _, ociCluster := range list.Items {
    48  		analyzeOCICluster(clusterRoot, ociCluster, issueReporter)
    49  	}
    50  
    51  	return nil
    52  }
    53  
    54  // analyzeOCICluster - analyze a single cluster API ocicluster and report any issues
    55  func analyzeOCICluster(clusterRoot string, ociCluster ociCluster, issueReporter *report.IssueReporter) {
    56  
    57  	var messages []string
    58  	var subMessage string
    59  	if !ociCluster.Status.Ready {
    60  		if len(ociCluster.Status.Conditions) == 0 {
    61  			message := fmt.Sprintf("%q resource %q in namespace %q, %s", ociClustersResource, ociCluster.Name, ociCluster.Namespace, "is not ready")
    62  			messages = append([]string{message}, messages...)
    63  		} else {
    64  			for _, condition := range ociCluster.Status.Conditions {
    65  				if condition.Status != corev1.ConditionTrue {
    66  					switch condition.Type {
    67  					case "ClusterReady":
    68  						subMessage = "cluster is not ready"
    69  					case "Ready":
    70  						subMessage = "is not ready"
    71  					default:
    72  						continue
    73  					}
    74  					// Add a message for the issue
    75  					var message string
    76  					if len(condition.Reason) == 0 {
    77  						message = fmt.Sprintf("\t%s", subMessage)
    78  					} else {
    79  						message = fmt.Sprintf("\t%s - reason is %s", subMessage, condition.Reason)
    80  					}
    81  					messages = append([]string{message}, messages...)
    82  
    83  				}
    84  			}
    85  		}
    86  	}
    87  
    88  	if len(messages) > 0 {
    89  		messages = append([]string{fmt.Sprintf("%q resource %q in namespace %q", ociClustersResource, ociCluster.Name, ociCluster.Namespace)}, messages...)
    90  		issueReporter.AddKnownIssueMessagesFiles(report.ClusterAPIClusterIssues, clusterRoot, messages, []string{})
    91  	}
    92  }