|
1 | 1 | // This file is part of arduino-cloud-cli.
|
2 | 2 | //
|
3 |
| -// Copyright (C) 2021 ARDUINO SA (http://www.arduino.cc/) |
| 3 | +// Copyright (C) 2024 ARDUINO SA (http://www.arduino.cc/) |
4 | 4 | //
|
5 | 5 | // This program is free software: you can redistribute it and/or modify
|
6 | 6 | // it under the terms of the GNU Affero General Public License as published
|
|
18 | 18 | package template
|
19 | 19 |
|
20 | 20 | import (
|
| 21 | + "context" |
21 | 22 | "fmt"
|
22 | 23 |
|
23 | 24 | "github.com/arduino/arduino-cli/cli/feedback"
|
24 | 25 | "github.com/arduino/arduino-cloud-cli/config"
|
| 26 | + "github.com/arduino/arduino-cloud-cli/internal/iot" |
25 | 27 | storageapi "github.com/arduino/arduino-cloud-cli/internal/storage-api"
|
| 28 | + iotclient "github.com/arduino/iot-client-go/v2" |
26 | 29 | "github.com/gofrs/uuid"
|
27 | 30 | "github.com/sirupsen/logrus"
|
28 | 31 | )
|
29 | 32 |
|
30 |
| -func ApplyCustomTemplates(cred *config.Credentials, templateId string) error { |
| 33 | +func ApplyCustomTemplates(cred *config.Credentials, templateId, deviceId, prefix string, networkCredentials map[string]string) error { |
31 | 34 |
|
| 35 | + ctx := context.Background() |
| 36 | + |
| 37 | + // Open clients |
32 | 38 | apiclient := storageapi.NewClient(cred)
|
| 39 | + iotClient, err := iot.NewClient(cred) |
| 40 | + if err != nil { |
| 41 | + return err |
| 42 | + } |
33 | 43 |
|
34 |
| - feedback.Printf("Applying template %s", templateId) |
| 44 | + feedback.Printf("Applying template %s to device %s", templateId, deviceId) |
35 | 45 |
|
36 | 46 | templateIdUUID, err := uuid.FromString(templateId)
|
37 | 47 | if err != nil {
|
38 | 48 | return fmt.Errorf("invalid template id: %s", templateId)
|
39 | 49 | }
|
| 50 | + |
| 51 | + // Get custom template and verify it is present |
40 | 52 | cstTemplate, err := apiclient.GetCustomTemplate(templateIdUUID)
|
41 | 53 | if err != nil {
|
42 | 54 | return err
|
43 | 55 | }
|
44 |
| - if len(cstTemplate.ThingTemplates) > 0 { |
45 |
| - mainThing := cstTemplate.ThingTemplates[0] |
46 |
| - logrus.Debug("Main thing template - id: ", mainThing.Id) |
47 |
| - //TODO check thing ID proceed |
| 56 | + if len(cstTemplate.ThingTemplates) <= 0 { |
| 57 | + return fmt.Errorf("template %s has no thing template", templateId) |
48 | 58 | }
|
| 59 | + mainThing := cstTemplate.ThingTemplates[0] |
| 60 | + logrus.Debug("Main thing template - id: ", mainThing.Id) |
49 | 61 |
|
| 62 | + // Get device and check its connectivity |
| 63 | + secrets, err := resolveDeviceNetworkConfigurations(ctx, iotClient, deviceId, networkCredentials) |
| 64 | + if err != nil { |
| 65 | + return err |
| 66 | + } |
| 67 | + for key, value := range secrets { |
| 68 | + logrus.Info(fmt.Sprintf("Secret %s: %s", key, value)) |
| 69 | + } |
50 | 70 | return nil
|
51 | 71 | }
|
| 72 | + |
| 73 | +func resolveDeviceNetworkConfigurations(ctx context.Context, cl *iot.Client, deviceId string, networkCredentials map[string]string) (map[string]string, error) { |
| 74 | + device, err := cl.DeviceShow(ctx, deviceId) |
| 75 | + if err != nil { |
| 76 | + return nil, err |
| 77 | + } |
| 78 | + if device.Type == "" || device.ConnectionType == nil { |
| 79 | + logrus.Warnf("Device %s has no type or connection-type - type: %s", deviceId, device.Type) |
| 80 | + return nil, nil // cannot take a decision on this device, try to proceed |
| 81 | + } |
| 82 | + logrus.Infof("Device %s - type: %s - connection-type: %s", deviceId, device.Type, *device.ConnectionType) |
| 83 | + |
| 84 | + credentials, err := cl.DeviceNetworkCredentials(ctx, device.Type, *device.ConnectionType) |
| 85 | + if err != nil { |
| 86 | + return nil, err |
| 87 | + } |
| 88 | + |
| 89 | + // Check if the provided network credentials are valid. Verify if all the required credentials are present. |
| 90 | + discoveredCredentials := make(map[string]iotclient.ArduinoCredentialsv1) |
| 91 | + for _, credential := range credentials { |
| 92 | + discoveredCredentials[credential.GetSecretName()] = credential |
| 93 | + if credential.Required { |
| 94 | + if _, ok := networkCredentials[credential.GetSecretName()]; !ok { |
| 95 | + return nil, fmt.Errorf("missing mandatory network credential: %s", credential.GetSecretName()) |
| 96 | + } |
| 97 | + } |
| 98 | + } |
| 99 | + // Remove any property that is not supported |
| 100 | + for key := range networkCredentials { |
| 101 | + if _, ok := discoveredCredentials[key]; !ok { |
| 102 | + delete(networkCredentials, key) |
| 103 | + } |
| 104 | + } |
| 105 | + |
| 106 | + return networkCredentials, nil |
| 107 | +} |
0 commit comments