1 package registrar
2
3 import (
4 "context"
5 "fmt"
6 "time"
7
8 "github.com/shurcooL/graphql"
9
10 edgeClient "edge-infra.dev/pkg/edge/api/client"
11 "edge-infra.dev/pkg/edge/api/graph/model"
12 )
13
14
15 type Registrar struct {
16 Client *edgeClient.EdgeClient
17 }
18
19 func (registrar *Registrar) GetBFFClient() *edgeClient.EdgeClient {
20 return registrar.Client
21 }
22
23 func (registrar *Registrar) GetBanner(ctx context.Context, bannerName string, bffClient *edgeClient.EdgeClient) (Banner, error) {
24 var query struct {
25 Banners []Banner `graphql:"banners()"`
26 }
27
28 err := bffClient.Query(ctx, &query, map[string]interface{}{})
29 if err != nil {
30 fmt.Println("an error occurred retrieving banner:", err.Error())
31 }
32
33 banners := query.Banners
34
35 for _, banner := range banners {
36 if banner.Name == bannerName {
37 fmt.Println("retrieved banner:", banner.BannerEdgeID)
38 return banner, nil
39 }
40 }
41
42 return Banner{}, fmt.Errorf("could not find banner: %s: %v", bannerName, err)
43 }
44
45 func (registrar *Registrar) GetCluster(ctx context.Context, storeName, bannerName string) (Cluster, error) {
46 bffClient := registrar.GetBFFClient()
47
48 banner, err := registrar.GetBanner(ctx, bannerName, bffClient)
49 if err != nil {
50 return Cluster{}, err
51 }
52
53 var query struct {
54 Clusters []Cluster `graphql:"clusters(bannerEdgeId: $bannerEdgeId)"`
55 }
56
57 err = bffClient.Query(ctx, &query, map[string]interface{}{"bannerEdgeId": graphql.String(banner.BannerEdgeID)})
58 if err != nil {
59 return Cluster{}, fmt.Errorf("fail to call bff graphql clusters: %v", err)
60 }
61
62 clusters := query.Clusters
63
64 for _, cluster := range clusters {
65 if cluster.ClusterName == storeName {
66 fmt.Println("retrieved cluster:", cluster.ClusterEdgeID)
67 return cluster, nil
68 }
69 }
70
71 return Cluster{}, fmt.Errorf("cluster does not exist: %s", storeName)
72 }
73
74 func (registrar *Registrar) GetTerminal(ctx context.Context, terminalID string) (*model.Terminal, error) {
75 bffClient := registrar.GetBFFClient()
76
77 var query struct {
78 model.Terminal `graphql:"terminal(terminalId: $terminalId)"`
79 }
80 variables := map[string]interface{}{
81 "terminalId": graphql.String(terminalID),
82 }
83
84 if err := bffClient.Query(ctx, &query, variables); err != nil {
85 return nil, err
86 }
87 return &query.Terminal, nil
88 }
89
90 func (registrar *Registrar) RegisterTerminal(
91 ctx context.Context,
92 terminalInput model.TerminalCreateInput,
93 ) (*model.Terminal, error) {
94
95 bffClient := registrar.GetBFFClient()
96
97 var mutation struct {
98 model.Terminal `graphql:"createTerminal(newTerminal: $terminalInput)"`
99 }
100 variables := map[string]interface{}{
101 "terminalInput": terminalInput,
102 }
103 err := bffClient.Mutate(ctx, &mutation, variables)
104 if err != nil {
105 return nil, fmt.Errorf("fail to call bff graphql createTerminal: %v", err)
106 }
107 return &mutation.Terminal, nil
108 }
109
110 func (registrar *Registrar) RegisterTerminals(terminals []*model.TerminalCreateInput) ([]*model.Terminal, error) {
111 var terms []*model.Terminal
112
113 for _, terminal := range terminals {
114
115
116
117 term, err := func() (*model.Terminal, error) {
118 reqCtx, cancelReq := context.WithTimeout(context.Background(), time.Duration(30)*time.Second)
119 defer cancelReq()
120
121 term, err := registrar.RegisterTerminal(reqCtx, *terminal)
122
123 return term, err
124 }()
125
126 if err != nil {
127 return nil, err
128 }
129
130 terms = append(terms, term)
131 }
132 return terms, nil
133 }
134
135 func (registrar *Registrar) DeleteTerminal(ctx context.Context, terminalID string) (bool, error) {
136 bffClient := registrar.GetBFFClient()
137
138 var mutation struct {
139 Status graphql.Boolean `graphql:"deleteTerminal(terminalId: $terminalId)"`
140 }
141 variables := map[string]interface{}{
142 "terminalId": graphql.String(terminalID),
143 }
144 err := bffClient.Mutate(ctx, &mutation, variables)
145 if err != nil {
146 return false, fmt.Errorf("failed to call bff graphql deleteTerminal: %v", err)
147 }
148 return bool(mutation.Status), nil
149 }
150
151 func (registrar *Registrar) DeleteTerminalDisk(ctx context.Context, terminalDiskID string) (bool, error) {
152 bffClient := registrar.GetBFFClient()
153
154 var mutation struct {
155 Status graphql.Boolean `graphql:"deleteTerminalDisk(terminalDiskId: $terminalDiskId)"`
156 }
157 variables := map[string]interface{}{
158 "terminalDiskId": graphql.String(terminalDiskID),
159 }
160 err := bffClient.Mutate(ctx, &mutation, variables)
161 if err != nil {
162 return false, fmt.Errorf("failed to call bff graphql deleteTerminalDisk: %v", err)
163 }
164 return bool(mutation.Status), nil
165 }
166
167 func (registrar *Registrar) ModifyTerminal(ctx context.Context, terminalID string, terminalValues *model.TerminalUpdateInput) (*model.Terminal, error) {
168 bffClient := registrar.GetBFFClient()
169 var mutation struct {
170 NewTerminal model.Terminal `graphql:"updateTerminal(terminal: {terminalId: $terminalId, terminalValues: $terminalValues})"`
171 }
172
173 variables := map[string]interface{}{
174 "terminalId": graphql.String(terminalID),
175 "terminalValues": *terminalValues,
176 }
177 if err := bffClient.Mutate(ctx, &mutation, variables); err != nil {
178 return nil, err
179 }
180 return &mutation.NewTerminal, nil
181 }
182
183 func (registrar *Registrar) ModifyTerminalInterface(ctx context.Context, terminalInterfaceID string, updatedInterfaceInput *model.TerminalInterfaceUpdateInput) (*model.TerminalInterface, error) {
184 bffClient := registrar.GetBFFClient()
185 var mutation struct {
186 UpdatedTerminalInterface model.TerminalInterface `graphql:"updateTerminalInterface(interface: {terminalInterfaceId: $terminalInterfaceId, terminalInterfaceValues: $terminalInterfaceValues})"`
187 }
188
189 variables := map[string]interface{}{
190 "terminalInterfaceId": graphql.String(terminalInterfaceID),
191 "terminalInterfaceValues": *updatedInterfaceInput,
192 }
193 if err := bffClient.Mutate(ctx, &mutation, variables); err != nil {
194 return nil, err
195 }
196 return &mutation.UpdatedTerminalInterface, nil
197 }
198
199 func (registrar *Registrar) ModifyTerminalAddress(ctx context.Context, terminalAddressID string, updatedAddressInput *model.TerminalAddressUpdateInput) (*model.TerminalAddress, error) {
200 bffClient := registrar.GetBFFClient()
201 var mutation struct {
202 UpdatedTerminalAddress model.TerminalAddress `graphql:"updateTerminalAddress(address: {terminalAddressId: $terminalAddressId, terminalAddressValues: $terminalAddressValues})"`
203 }
204
205 variables := map[string]interface{}{
206 "terminalAddressId": graphql.String(terminalAddressID),
207 "terminalAddressValues": *updatedAddressInput,
208 }
209 if err := bffClient.Mutate(ctx, &mutation, variables); err != nil {
210 return nil, err
211 }
212 return &mutation.UpdatedTerminalAddress, nil
213 }
214
215 func (registrar *Registrar) ModifyTerminalDisk(ctx context.Context, terminalDiskID string, updateDiskInput *model.TerminalDiskUpdateInput) (*model.TerminalDisk, error) {
216 bffClient := registrar.GetBFFClient()
217 var mutation struct {
218 UpdatedTerminalDisk model.TerminalDisk `graphql:"updateTerminalDisk(terminalDisk: {terminalDiskId: $terminalDiskId, terminalDiskValues: $terminalDiskValues})"`
219 }
220
221 variables := map[string]interface{}{
222 "terminalDiskId": graphql.String(terminalDiskID),
223 "terminalDiskValues": *updateDiskInput,
224 }
225 if err := bffClient.Mutate(ctx, &mutation, variables); err != nil {
226 return nil, err
227 }
228 return &mutation.UpdatedTerminalDisk, nil
229 }
230
231 func (registrar *Registrar) RegisterNetworkServices(
232 ctx context.Context,
233 clusterEdgeID string,
234 networkServices []model.CreateNetworkServiceInfo,
235 ) ([]model.ClusterNetworkServiceInfo, error) {
236
237 bffClient := registrar.GetBFFClient()
238
239 var mutation struct {
240 NetworkServices []model.ClusterNetworkServiceInfo `graphql:"createClusterNetworkServices(clusterEdgeId: $clusterEdgeId, networkServicesInfo: $networkServicesInfo)"`
241 }
242 variables := map[string]interface{}{
243 "clusterEdgeId": graphql.String(clusterEdgeID),
244 "networkServicesInfo": networkServices,
245 }
246 err := bffClient.Mutate(ctx, &mutation, variables)
247 if err != nil {
248 return nil, fmt.Errorf("fail to call bff graphql createClusterNetworkServices: %v", err)
249 }
250 return mutation.NetworkServices, nil
251 }
252
253 func (registrar *Registrar) ModifyNetworkServices(
254 ctx context.Context,
255 clusterEdgeID string,
256 networkServices []model.UpdateNetworkServiceInfo,
257 ) ([]model.ClusterNetworkServiceInfo, error) {
258
259 bffClient := registrar.GetBFFClient()
260
261 var mutation struct {
262 NetworkServices []model.ClusterNetworkServiceInfo `graphql:"updateClusterNetworkServices(clusterEdgeId: $clusterEdgeId, networkServicesInfo: $networkServicesInfo)"`
263 }
264 variables := map[string]interface{}{
265 "clusterEdgeId": graphql.String(clusterEdgeID),
266 "networkServicesInfo": networkServices,
267 }
268 err := bffClient.Mutate(ctx, &mutation, variables)
269 if err != nil {
270 return nil, fmt.Errorf("fail to call bff graphql updateClusterNetworkServices: %v", err)
271 }
272 return mutation.NetworkServices, nil
273 }
274
275 func (registrar *Registrar) DeleteNetworkServices(
276 ctx context.Context,
277 clusterEdgeID string,
278 networkServiceID string,
279 ) (bool, error) {
280
281 bffClient := registrar.GetBFFClient()
282
283 var mutation struct {
284 Status graphql.Boolean `graphql:"deleteClusterNetworkService(clusterEdgeId: $clusterEdgeId, networkServiceId: $networkServiceId)"`
285 }
286 variables := map[string]interface{}{
287 "clusterEdgeId": graphql.String(clusterEdgeID),
288 "networkServiceId": graphql.String(networkServiceID),
289 }
290 err := bffClient.Mutate(ctx, &mutation, variables)
291 if err != nil {
292 return false, fmt.Errorf("fail to call bff graphql deleteClusterNetworkService: %v", err)
293 }
294 return bool(mutation.Status), nil
295 }
296
297 func (registrar *Registrar) UpdateClusterSecret(ctx context.Context, clusterEdgeID, secretType, secretValue string) error {
298 clusterSecretType, err := validateSecretType(secretType)
299 if err != nil {
300 return err
301 }
302
303 bffClient := registrar.GetBFFClient()
304 var mutation struct {
305 Status graphql.Boolean `graphql:"updateClusterSecret(clusterEdgeId: $clusterEdgeId, secretType: $secretType, secretValue: $secretValue)"`
306 }
307
308 variables := map[string]interface{}{
309 "clusterEdgeId": graphql.String(clusterEdgeID),
310 "secretType": clusterSecretType,
311 "secretValue": graphql.String(secretValue),
312 }
313 err = bffClient.Mutate(ctx, &mutation, variables)
314 if err != nil {
315 return fmt.Errorf("fail to call bff graphql updateClusterSecret: %v", err)
316 }
317 return nil
318 }
319
320 func (registrar *Registrar) RefreshActivationCode(ctx context.Context, terminalID string) (string, error) {
321 bffClient := registrar.GetBFFClient()
322 var mutation struct {
323 ActivationCode graphql.String `graphql:"refreshActivationCode(terminalId: $terminalId)"`
324 }
325
326 variables := map[string]interface{}{
327 "terminalId": graphql.String(terminalID),
328 }
329 if err := bffClient.Mutate(ctx, &mutation, variables); err != nil {
330 return "", err
331 }
332 return string(mutation.ActivationCode), nil
333 }
334
335 func (registrar *Registrar) GetActivationCode(ctx context.Context, terminalID string) (string, error) {
336 bffClient := registrar.GetBFFClient()
337 var query struct {
338 ActivationCode graphql.String `graphql:"activationCode(terminalId: $terminalId)"`
339 }
340
341 variables := map[string]interface{}{
342 "terminalId": graphql.String(terminalID),
343 }
344 if err := bffClient.Query(ctx, &query, variables); err != nil {
345 return "", err
346 }
347 return string(query.ActivationCode), nil
348 }
349
350 func (registrar *Registrar) CreateClusterConfig(ctx context.Context, clusterEdgeID string, clusterConfig model.CreateClusterConfig) error {
351 bffClient := registrar.GetBFFClient()
352 var mutation struct {
353 CreateClusterConfig model.ClusterConfig `graphql:"createClusterConfig(clusterEdgeId: $clusterEdgeId, createClusterConfig: $createClusterConfig)"`
354 }
355
356 variables := map[string]interface{}{
357 "clusterEdgeId": graphql.String(clusterEdgeID),
358 "createClusterConfig": clusterConfig,
359 }
360 return bffClient.Mutate(ctx, &mutation, variables)
361 }
362
363 func (registrar *Registrar) GetTerminals(ctx context.Context, clusterEdgeID string) ([]*model.Terminal, error) {
364 bffClient := registrar.GetBFFClient()
365
366 var query struct {
367 Terminals []*model.Terminal `graphql:"terminals(clusterEdgeId: $clusterEdgeId)"`
368 }
369
370 if err := bffClient.Query(ctx, &query, map[string]interface{}{"clusterEdgeId": graphql.String(clusterEdgeID)}); err != nil {
371 return query.Terminals, fmt.Errorf("fail to call bff graphql terminals: %v", err)
372 }
373
374 return query.Terminals, nil
375 }
376
377 func (registrar *Registrar) UpdateClusterConfig(ctx context.Context, clusterEdgeID string, clusterConfig model.UpdateClusterConfig) error {
378 bffClient := registrar.GetBFFClient()
379 var mutation struct {
380 UpdateClusterConfig model.ClusterConfig `graphql:"updateClusterConfig(clusterEdgeId: $clusterEdgeId, updateClusterConfig: $updateClusterConfig)"`
381 }
382
383 variables := map[string]interface{}{
384 "clusterEdgeId": graphql.String(clusterEdgeID),
385 "updateClusterConfig": clusterConfig,
386 }
387 return bffClient.Mutate(ctx, &mutation, variables)
388 }
389
390 func (registrar *Registrar) GetClusterConfig(ctx context.Context, clusterEdgeID string) (*model.ClusterConfig, error) {
391 bffClient := registrar.GetBFFClient()
392 var query struct {
393 ClusterConfig *model.ClusterConfig `graphql:"clusterConfig(clusterEdgeId: $clusterEdgeId)"`
394 }
395 variables := map[string]interface{}{
396 "clusterEdgeId": graphql.String(clusterEdgeID),
397 }
398
399 if err := bffClient.Query(ctx, &query, variables); err != nil {
400 return nil, err
401 }
402
403 return query.ClusterConfig, nil
404 }
405
406 func (registrar *Registrar) GetClusterSecret(ctx context.Context, clusterEdgeID string, st string, version string) (string, error) {
407 secretType, err := validateSecretType(st)
408 if err != nil {
409 return "", err
410 }
411
412 bffClient := registrar.GetBFFClient()
413
414 var query struct {
415 ClusterSecret string `graphql:"clusterSecret(clusterEdgeID: $clusterEdgeID, secretType: $secretType, version: $version)"`
416 }
417
418 if err := bffClient.Query(ctx, &query, map[string]interface{}{"clusterEdgeID": graphql.String(clusterEdgeID), "secretType": secretType, "version": graphql.String(version)}); err != nil {
419 return query.ClusterSecret, fmt.Errorf("failed to call bff graphql clusterSecret: %v", err)
420 }
421
422 return query.ClusterSecret, nil
423 }
424
425 func (registrar *Registrar) GetClusterSecretVersions(ctx context.Context, clusterEdgeID string, st string) ([]*model.ClusterSecretVersionInfo, error) {
426 secretType, err := validateSecretType(st)
427 if err != nil {
428 return []*model.ClusterSecretVersionInfo{}, err
429 }
430
431 bffClient := registrar.GetBFFClient()
432
433 var query struct {
434 ClusterSecretVersions []*model.ClusterSecretVersionInfo `graphql:"clusterSecretVersions(clusterEdgeID: $clusterEdgeID, secretType: $secretType)"`
435 }
436
437 if err := bffClient.Query(ctx, &query, map[string]interface{}{"clusterEdgeID": graphql.String(clusterEdgeID), "secretType": secretType}); err != nil {
438 return query.ClusterSecretVersions, fmt.Errorf("failed to call bff graphql clusterSecret: %v", err)
439 }
440
441 return query.ClusterSecretVersions, nil
442 }
443
444 func (registrar *Registrar) GetClusterSecretLease(ctx context.Context, clusterEdgeID string, st string) (*model.ClusterSecretLease, error) {
445 secretType, err := validateSecretType(st)
446 if err != nil {
447 return nil, err
448 }
449 bffClient := registrar.GetBFFClient()
450
451 var query struct {
452 ClusterSecretLease model.ClusterSecretLease `graphql:"clusterSecretLease(clusterEdgeID: $clusterEdgeID, secretType: $secretType)"`
453 }
454 if err := bffClient.Query(ctx, &query, map[string]interface{}{"clusterEdgeID": graphql.String(clusterEdgeID), "secretType": secretType}); err != nil {
455 return nil, fmt.Errorf("failed to call bff graphql clusterSecretLease: %v", err)
456 }
457
458 return &query.ClusterSecretLease, nil
459 }
460
461 func (registrar *Registrar) RevokeClusterSecretLease(ctx context.Context, clusterEdgeID string, st string, username string) (bool, error) {
462 secretType, err := validateSecretType(st)
463 if err != nil {
464 return false, err
465 }
466
467 bffClient := registrar.GetBFFClient()
468
469 var mutation struct {
470 RevokeClusterSecretLease bool `graphql:"revokeClusterSecretLease(clusterEdgeId: $clusterEdgeID, secretType: $secretType, username: $username)"`
471 }
472
473 if err := bffClient.Mutate(ctx, &mutation, map[string]interface{}{"clusterEdgeID": graphql.String(clusterEdgeID), "secretType": secretType, "username": graphql.String(username)}); err != nil {
474 return mutation.RevokeClusterSecretLease, fmt.Errorf("failed to call bff graphql revokeClusterSecretLease: %v", err)
475 }
476 return mutation.RevokeClusterSecretLease, nil
477 }
478 func (registrar *Registrar) ReleaseClusterSecretLease(ctx context.Context, clusterEdgeID string, st string) (bool, error) {
479 secretType, err := validateSecretType(st)
480 if err != nil {
481 return false, err
482 }
483
484 bffClient := registrar.GetBFFClient()
485
486 var mutation struct {
487 RevokeClusterSecretLease bool `graphql:"releaseClusterSecretLease(clusterEdgeId: $clusterEdgeID, secretType: $secretType)"`
488 }
489
490 if err := bffClient.Mutate(ctx, &mutation, map[string]interface{}{"clusterEdgeID": graphql.String(clusterEdgeID), "secretType": secretType}); err != nil {
491 return mutation.RevokeClusterSecretLease, fmt.Errorf("failed to call bff graphql releaseClusterSecretLease: %v", err)
492 }
493
494 return mutation.RevokeClusterSecretLease, nil
495 }
496
497 func (registrar *Registrar) UpdateEdgeSecurityCompliance(ctx context.Context, bannerName string, optIn string) (*model.EdgeResponsePayload, error) {
498 var edgeSecurityCompliance model.EdgeSecurityComplianceOptions
499 bffClient := registrar.GetBFFClient()
500 banner, err := registrar.GetBanner(ctx, bannerName, bffClient)
501 if err != nil {
502 return &model.EdgeResponsePayload{}, err
503 }
504 if optIn == "true" {
505 edgeSecurityCompliance = "optIn"
506 } else if optIn == "false" {
507 edgeSecurityCompliance = "optOut"
508 } else if optIn == "default" {
509 edgeSecurityCompliance = "default"
510 } else {
511 return &model.EdgeResponsePayload{}, fmt.Errorf("invalid security compliance option. must choose from true, false or default")
512 }
513 var mutation struct {
514 UpdateEdgeSecurityCompliance *model.EdgeResponsePayload `graphql:"updateBanner(bannerEdgeId: $bannerEdgeID, edgeSecurityCompliance: $securityCompliance)"`
515 }
516
517 if err := bffClient.Mutate(ctx, &mutation, map[string]interface{}{"bannerEdgeID": graphql.String(banner.BannerEdgeID), "securityCompliance": edgeSecurityCompliance}); err != nil {
518 return mutation.UpdateEdgeSecurityCompliance, fmt.Errorf("failed to call bff graphql updateBanner: %v", err)
519 }
520
521 return mutation.UpdateEdgeSecurityCompliance, nil
522 }
523
524 func (registrar *Registrar) CreateTerminalDisk(ctx context.Context, terminalID string, newTerminalDisk model.TerminalDiskCreateInput) error {
525 bffClient := registrar.GetBFFClient()
526
527 var mutation struct {
528 CreateTerminalDisk model.TerminalDisk `graphql:"createTerminalDisk(terminalId: $terminalId, newTerminalDisk: $newTerminalDisk)"`
529 }
530
531 variables := map[string]interface{}{
532 "terminalId": graphql.String(terminalID),
533 "newTerminalDisk": newTerminalDisk,
534 }
535
536 return bffClient.Mutate(ctx, &mutation, variables)
537 }
538
539 func validateSecretType(secretType string) (model.ClusterSecretType, error) {
540 switch secretType {
541 case "breakglass":
542 return model.ClusterSecretTypeBreakglass, nil
543 case "grub":
544 return model.ClusterSecretTypeGrub, nil
545 default:
546 return model.ClusterSecretTypeBreakglass, fmt.Errorf("invalid secret type %s", secretType)
547 }
548 }
549
550
551 type Banner struct {
552
553 BannerEdgeID string `graphql:"bannerEdgeId" json:"bannerEdgeId"`
554 Name string `graphql:"name" json:"name"`
555 }
556
557
558 type Cluster struct {
559
560 ClusterEdgeID string `graphql:"clusterEdgeId" json:"clusterEdgeId"`
561 ClusterName string `graphql:"name" json:"clusterName"`
562 ClusterNetworkServices []*model.ClusterNetworkServiceInfo `graphql:"clusterNetworkServices" json:"clusterNetworkServices"`
563 }
564
View as plain text