1
6 package usestorage
7
8 import (
9 "context"
10 "database/sql"
11 "encoding/json"
12 "errors"
13 "fmt"
14 "io"
15 "os"
16 "strings"
17
18 "cloud.google.com/go/storage"
19 "google.golang.org/api/iterator"
20 corev1 "k8s.io/api/core/v1"
21
22 eyedeUtils "edge-infra.dev/hack/tools/eyede/utils"
23 "edge-infra.dev/pkg/edge/api/utils"
24 "edge-infra.dev/pkg/edge/info"
25 )
26
27 const (
28 edgeInfoConfigMapMatcher = "{\"kind\":\"ConfigMap\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"edge-info\""
29 updateClusterWithLocation = "UPDATE clusters SET location = $1 WHERE cluster_edge_id = $2"
30 )
31
32 func UpdateEdgeInfoConfigMapsInStorage(ctx context.Context, db *sql.DB, projectID, foremanProjectID, topic, edgeAPIURL string, dryRun bool) bool {
33 client, err := storage.NewClient(ctx)
34 if err != nil {
35 fmt.Println("an error occurred creating storage client", err)
36 os.Exit(1)
37 }
38 bucket := client.Bucket(projectID)
39 it := bucket.Objects(ctx, nil)
40 for {
41 attrs, err := it.Next()
42 if err == iterator.Done {
43 break
44 }
45 if err != nil {
46 switch {
47 case errors.Is(err, storage.ErrBucketNotExist):
48 return true
49 case errors.Is(err, storage.ErrObjectNotExist):
50 continue
51 default:
52 fmt.Println("an error occurred", projectID, err)
53 os.Exit(1)
54 }
55 }
56 if isChariotObject(attrs.Name) {
57 data := readObject(ctx, bucket, attrs.Name)
58 if isEdgeInfoConfigMap(data) {
59 edgeInfoConfigmap := objectToConfigMap(data)
60 edgeInfo := &info.EdgeInfo{}
61 edgeInfo = edgeInfo.FromConfigMap(edgeInfoConfigmap)
62 edgeInfo.EdgeAPIEndpoint = edgeAPIURL
63 edgeCM := edgeInfo.ToConfigMap()
64 edgeConfigMapString, err := info.ConfigMapToString(edgeCM)
65 if err != nil {
66 fmt.Println("error converting configmap to string", err)
67 os.Exit(1)
68 }
69 fmt.Println(string(edgeConfigMapString))
70 fmt.Println("")
71 if !dryRun {
72 configMap := utils.ToBase64(edgeConfigMapString)
73 chariotMessage := eyedeUtils.CreateChariotMessage(edgeInfo.ProjectID, edgeInfo.ClusterEdgeID, eyedeUtils.Filter, configMap)
74 err = eyedeUtils.InvokeChariot(ctx, foremanProjectID, topic, chariotMessage)
75 if err != nil {
76 fmt.Println("failed to send configmap to chariot", err)
77 os.Exit(1)
78 }
79
80 _, err = db.ExecContext(ctx, updateClusterWithLocation, edgeInfo.Location, edgeInfo.ClusterEdgeID)
81 if err != nil {
82 fmt.Println("error occurred updating the location of cluster in the database", edgeInfo.Store, edgeInfo.ClusterEdgeID)
83 }
84 }
85 }
86 }
87 }
88 return false
89 }
90
91 func readObject(ctx context.Context, bucket *storage.BucketHandle, objectName string) []byte {
92 obj := bucket.Object(objectName)
93 rdr, err := obj.NewReader(ctx)
94 if err != nil {
95 fmt.Println("failed to create reader for file in chariot folder", objectName, err)
96 os.Exit(1)
97 }
98 data, err := io.ReadAll(rdr)
99 if err != nil || rdr.Close() != nil {
100 fmt.Println("failed to read file in chariot folder", objectName, err)
101 os.Exit(1)
102 }
103 return data
104 }
105
106 func isChariotObject(objectName string) bool {
107 return strings.Contains(objectName, eyedeUtils.Filter)
108 }
109
110 func isEdgeInfoConfigMap(fileContents []byte) bool {
111 return strings.Contains(string(fileContents), edgeInfoConfigMapMatcher)
112 }
113
114 func objectToConfigMap(data []byte) *corev1.ConfigMap {
115 edgeInfoConfigmap := &corev1.ConfigMap{}
116 err := json.Unmarshal(data, edgeInfoConfigmap)
117 if err != nil {
118 fmt.Println("failed to unmarshal object to configmap", err)
119 os.Exit(1)
120 }
121 return edgeInfoConfigmap
122 }
123
View as plain text