...
1 package edgedb
2
3 import (
4 "context"
5 "fmt"
6 "time"
7
8 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9
10 bannerApi "edge-infra.dev/pkg/edge/apis/banner/v1alpha1"
11 clusterApi "edge-infra.dev/pkg/edge/apis/cluster/v1alpha1"
12 gkeclusterApi "edge-infra.dev/pkg/edge/apis/gkecluster/v1alpha1"
13 "edge-infra.dev/pkg/edge/controllers/dbmetrics"
14 "edge-infra.dev/pkg/k8s/meta/status"
15 "edge-infra.dev/pkg/k8s/runtime/conditions"
16 "edge-infra.dev/pkg/lib/fog"
17 )
18
19
20 type InfraStatus string
21
22 const (
23 InfraStatusReady InfraStatus = "READY"
24 InfraStatusError InfraStatus = "ERROR"
25
26
27 InfraStatusProvisioning InfraStatus = "PROVISIONING"
28 )
29
30 const errorLogMessage = "Infra status not recorded"
31
32 const sqlUpdateClusterStatus = "UPDATE clusters SET infra_status=$1, infra_status_details=$2, infra_status_updated_at=$3 WHERE cluster_edge_id=$4"
33 const sqlUpdateBannerStatus = "UPDATE banners SET infra_status=$1, infra_status_details=$2, infra_status_updated_at=$3 WHERE banner_edge_id=$4"
34
35
36
37
38 func (edb *EdgeDB) RecordInfraStatus(ctx context.Context, obj conditions.Getter, recorder dbmetrics.DBMetrics) {
39 var log = fog.FromContext(ctx).WithName("dbinfrastatus")
40
41 if edb.DB == nil {
42
43 return
44 }
45
46
47 var stmt string
48 kind := obj.GetObjectKind().GroupVersionKind().Kind
49 switch kind {
50 case clusterApi.Kind, gkeclusterApi.Kind:
51 stmt = sqlUpdateClusterStatus
52 case bannerApi.BannerKind:
53 stmt = sqlUpdateBannerStatus
54 default:
55 err := fmt.Errorf("Kind not supported")
56 log.Error(err, errorLogMessage, "kind", kind)
57 return
58 }
59
60 var cv = columnValuesForObject(obj)
61 _, err := edb.DB.ExecContext(ctx, stmt, cv.InfraStatus, cv.InfraStatusDetails, cv.InfraStatusUpdatedAt, cv.EdgeID)
62 if err != nil {
63 log.Error(err, errorLogMessage)
64 recorder.RecordDBErrorsTotal(ctx, kind, obj.GetName())
65 } else {
66 recorder.RecordDBStatusWritesTotal(ctx, kind, toString(cv.InfraStatus))
67 }
68 }
69
70 type columnValues struct {
71 EdgeID string
72 InfraStatus InfraStatus
73 InfraStatusDetails string
74 InfraStatusUpdatedAt time.Time
75 }
76
77 func conditionStatusToInfraStatus(v metav1.ConditionStatus) InfraStatus {
78 if v == metav1.ConditionTrue {
79 return InfraStatusReady
80 } else if v == metav1.ConditionFalse {
81 return InfraStatusError
82 }
83 return InfraStatusProvisioning
84 }
85
86 func columnValuesForObject(obj conditions.Getter) columnValues {
87 for _, cs := range obj.GetConditions() {
88 if cs.Type == status.ReadyCondition {
89 return columnValues{
90 EdgeID: obj.GetName(),
91 InfraStatus: conditionStatusToInfraStatus(cs.Status),
92 InfraStatusDetails: fmt.Sprintf("%s: %s", cs.Reason, cs.Message),
93 InfraStatusUpdatedAt: cs.LastTransitionTime.Time,
94 }
95 }
96 }
97 return columnValues{
98 EdgeID: obj.GetName(),
99 InfraStatus: InfraStatusProvisioning,
100 InfraStatusDetails: "Ready condition not found",
101 InfraStatusUpdatedAt: time.Now(),
102 }
103 }
104
105 func toString(infraStatus InfraStatus) string {
106 switch infraStatus {
107 case InfraStatusReady:
108 return "Ready"
109 case InfraStatusError:
110 return "Error"
111 case InfraStatusProvisioning:
112 return "Provisioning"
113 default:
114 return "Unknown"
115 }
116 }
117
View as plain text