github.com/verrazzano/verrazzano@v1.7.1/tools/vz/pkg/internal/util/report/action.go (about) 1 // Copyright (c) 2021, 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 report handles reporting 5 package report 6 7 import ( 8 "errors" 9 "fmt" 10 11 "github.com/verrazzano/verrazzano/tools/vz/cmd/version" 12 "go.uber.org/zap" 13 ) 14 15 // TODO: Add helpers for working with Actions 16 17 // NOTE: This is part of the contract with the analyzers however it is currently an initial stake in the ground and 18 // will be evolving rapidly initially as we add analysis cases 19 20 // Action describes what a user/developer should do to mitigate an issue that has been found. For example: 21 // - Description of the action if more general 22 // - Link(s) to a Runbook(s) are preferable here as instructions may evolve over time and may be complex 23 // - A list of Steps to take 24 type Action struct { 25 Summary string // Required, Summary of the action to take 26 Links []string // Optional, runbook or other related Links with action details 27 Steps []string // Optional, list of Steps to take (pointing to runbook is preferable if Actions are complex) 28 } 29 30 // Validate validates the action 31 func (action *Action) Validate(log *zap.SugaredLogger) (err error) { 32 if len(action.Summary) == 0 { 33 return errors.New("A Summary is required for an Action") 34 } 35 return nil 36 } 37 38 // Standard Action Summaries 39 const ( 40 ConsultRunbook = "Consult %s using supporting details identified in the report" 41 ) 42 43 // RunbookLinks are known runbook links 44 var RunbookLinks = map[string][]string{ 45 ImagePullBackOff: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/imagepullbackoff"}, 46 ImagePullRateLimit: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/imagepullratelimit"}, 47 ImagePullNotFound: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/imagepullnotfound"}, 48 ImagePullService: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/imagepullservice"}, 49 InsufficientMemory: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/insufficientmemory"}, 50 InsufficientCPU: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/insufficientcpu"}, 51 IngressInstallFailure: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/ingressinstallfailure"}, 52 IngressLBLimitExceeded: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/ingresslblimitexceeded"}, 53 IngressNoLoadBalancerIP: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/ingressnoloadbalancerip"}, 54 IngressOciIPLimitExceeded: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/ingressociiplimitexceeded"}, 55 InstallFailure: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/installfailure"}, 56 PendingPods: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/pendingpods"}, 57 PodProblemsNotReported: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/podproblemsnotreported"}, 58 IngressNoIPFound: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/ingressnoloadbalancerip"}, 59 IstioIngressNoIP: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/istioingressgatewaynoloadbalancerip"}, 60 IngressShapeInvalid: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/ingressinvalidshape"}, 61 IstioIngressPrivateSubnet: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/istioloadbalancercreation"}, 62 NginxIngressPrivateSubnet: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/nginxloadbalancercreation"}, 63 ExternalDNSConfigureIssue: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/externaldnsconfiguration"}, 64 KeycloakDataMigrationFailure: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/keycloakdatamigrationfailure"}, 65 ClusterAPIClusterIssues: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/clusterapiclusterissues"}, 66 RancherIssues: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/rancherissues"}, 67 BlockStorageLimitExceeded: {"https://verrazzano.io/" + version.GetEffectiveDocsVersion() + "/docs/troubleshooting/diagnostictools/analysisadvice/blockstoragelimitexceeded"}, 68 } 69 70 // KnownActions are Standard Action types 71 var KnownActions = map[string]Action{ 72 ImagePullBackOff: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[ImagePullBackOff][0])}, 73 ImagePullRateLimit: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[ImagePullRateLimit][0])}, 74 ImagePullNotFound: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[ImagePullNotFound][0])}, 75 ImagePullService: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[ImagePullService][0])}, 76 InsufficientMemory: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[InsufficientMemory][0])}, 77 InsufficientCPU: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[InsufficientCPU][0])}, 78 IngressInstallFailure: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[IngressInstallFailure][0])}, 79 IngressLBLimitExceeded: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[IngressLBLimitExceeded][0])}, 80 IngressNoLoadBalancerIP: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[IngressNoLoadBalancerIP][0])}, 81 IngressOciIPLimitExceeded: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[IngressOciIPLimitExceeded][0])}, 82 InstallFailure: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[InstallFailure][0])}, 83 PendingPods: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[PendingPods][0])}, 84 PodProblemsNotReported: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[PodProblemsNotReported][0])}, 85 IngressNoIPFound: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[IngressNoIPFound][0])}, 86 IstioIngressNoIP: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[IstioIngressNoIP][0])}, 87 IngressShapeInvalid: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[IngressShapeInvalid][0])}, 88 IstioIngressPrivateSubnet: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[IstioIngressPrivateSubnet][0])}, 89 NginxIngressPrivateSubnet: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[NginxIngressPrivateSubnet][0])}, 90 ExternalDNSConfigureIssue: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[ExternalDNSConfigureIssue][0])}, 91 KeycloakDataMigrationFailure: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[KeycloakDataMigrationFailure][0])}, 92 ClusterAPIClusterIssues: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[ClusterAPIClusterIssues][0])}, 93 RancherIssues: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[RancherIssues][0])}, 94 BlockStorageLimitExceeded: {Summary: getConsultRunbookAction(ConsultRunbook, RunbookLinks[BlockStorageLimitExceeded][0])}, 95 } 96 97 func getConsultRunbookAction(summaryF string, runbookLink string) string { 98 return fmt.Sprintf(summaryF, runbookLink) 99 }