fix: on demand plant id generation (#21873)
This commit is contained in:
parent
d43ab9fa6a
commit
36b6036203
5 changed files with 82 additions and 50 deletions
|
|
@ -342,10 +342,7 @@ func (s *SEMP) serialNumber(id int) string {
|
|||
func UniqueDeviceID() ([]byte, error) {
|
||||
bytes := 6
|
||||
|
||||
mid, err := machine.ProtectedID("evcc-semp")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mid := machine.ProtectedID("evcc-semp")
|
||||
|
||||
b, err := hex.DecodeString(mid)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -79,10 +79,7 @@ func NewServer(other Config) (*EEBus, error) {
|
|||
|
||||
log := util.NewLogger("eebus")
|
||||
|
||||
protectedID, err := machine.ProtectedID("evcc-eebus")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
protectedID := machine.ProtectedID("evcc-eebus")
|
||||
serial := fmt.Sprintf("%s-%0x", "EVCC", protectedID[:8])
|
||||
|
||||
if len(cc.ShipID) != 0 {
|
||||
|
|
|
|||
|
|
@ -8,10 +8,15 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/denisbrodbeck/machineid"
|
||||
"github.com/evcc-io/evcc/core/keys"
|
||||
"github.com/evcc-io/evcc/server/db/settings"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
var id string
|
||||
var (
|
||||
id string
|
||||
getMachineID = machineid.ID
|
||||
)
|
||||
|
||||
// CustomID sets the machine id to a custom value
|
||||
func CustomID(cid string) error {
|
||||
|
|
@ -37,28 +42,37 @@ func RandomID() string {
|
|||
}
|
||||
|
||||
// ID returns the platform specific machine id of the current host OS.
|
||||
// If ID cannot be generated, a random value is suggested.
|
||||
func ID() (string, error) {
|
||||
// If ID cannot be generated, a random one from settings will be used (generated on demand)
|
||||
func ID() string {
|
||||
if id == "" {
|
||||
var err error
|
||||
if id, err = machineid.ID(); err != nil {
|
||||
rid := RandomID()
|
||||
return "", fmt.Errorf("could not get %w; for manual configuration use plant: %s", err, rid)
|
||||
if id, err = getMachineID(); err == nil && id != "" {
|
||||
return id
|
||||
}
|
||||
|
||||
// no machine id found, use is from settings
|
||||
return getOrCreateIDFromSettings()
|
||||
}
|
||||
|
||||
return id, nil
|
||||
return id
|
||||
}
|
||||
|
||||
// getOrCreateIDFromSettings return instance id from settings if exists, otherwise creates and stores a new one
|
||||
func getOrCreateIDFromSettings() string {
|
||||
if id, err := settings.String(keys.Plant); err == nil && id != "" {
|
||||
return id
|
||||
}
|
||||
|
||||
id := RandomID()
|
||||
settings.SetString(keys.Plant, id)
|
||||
|
||||
return id
|
||||
}
|
||||
|
||||
// ProtectedID returns a hashed version of the machine id
|
||||
// using a fixed, application-specific key.
|
||||
func ProtectedID(key string) (string, error) {
|
||||
id, err := ID()
|
||||
if err != nil {
|
||||
return id, err
|
||||
}
|
||||
|
||||
return protect(key, id), nil
|
||||
func ProtectedID(key string) string {
|
||||
return protect(key, ID())
|
||||
}
|
||||
|
||||
// protect calculates HMAC-SHA256 of the id, keyed by key and returns a hex-encoded string
|
||||
|
|
|
|||
|
|
@ -1,22 +1,65 @@
|
|||
package machine
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/denisbrodbeck/machineid"
|
||||
"github.com/evcc-io/evcc/core/keys"
|
||||
"github.com/evcc-io/evcc/server/db/settings"
|
||||
)
|
||||
|
||||
func TestProtectedMachineId(t *testing.T) {
|
||||
const key = "foo"
|
||||
|
||||
if mid, err := machineid.ProtectedID(key); err == nil {
|
||||
id, err := ProtectedID(key)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
id := ProtectedID(key)
|
||||
|
||||
if mid != id {
|
||||
t.Errorf("machine id mismatch. expected %s, got %s", mid, id)
|
||||
}
|
||||
} else {
|
||||
t.Skip("cannot get machineid, skipping test")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIdFromSettings(t *testing.T) {
|
||||
// reset machine id cache
|
||||
id = ""
|
||||
|
||||
// reset settings
|
||||
settings.Delete(keys.Plant)
|
||||
|
||||
// force machineid.ID() to fail
|
||||
getMachineID = func() (string, error) {
|
||||
return "", errors.New("dummy error")
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
getMachineID = machineid.ID
|
||||
})
|
||||
|
||||
// generate new random id
|
||||
generatedId := ID()
|
||||
if len(generatedId) != 64 {
|
||||
t.Errorf("expected 64 char id, got %d", len(generatedId))
|
||||
}
|
||||
|
||||
// check that id is stored in settings
|
||||
settingsId, _ := settings.String(keys.Plant)
|
||||
if generatedId != settingsId {
|
||||
t.Errorf("expected id %s, got %s from settings", generatedId, settingsId)
|
||||
}
|
||||
|
||||
// check reproducability
|
||||
idA1 := ProtectedID("A")
|
||||
idA2 := ProtectedID("A")
|
||||
idB := ProtectedID("B")
|
||||
|
||||
if idA1 != idA2 {
|
||||
t.Errorf("expected same id, got %s and %s", idA1, idA2)
|
||||
}
|
||||
|
||||
if idA1 == idB {
|
||||
t.Errorf("expected different id, got %s and %s", idA1, idB)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func Enable(enable bool) error {
|
|||
return errors.New("telemetry requires sponsorship")
|
||||
}
|
||||
if instanceID == "" {
|
||||
return fmt.Errorf("using docker? Telemetry requires a unique instance ID. Add this to your config: `plant: %s`", machine.RandomID())
|
||||
return fmt.Errorf("instance id not set")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -48,31 +48,12 @@ func Enable(enable bool) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// getOrCreateID return instance id from settings if exists, otherwise creates and stores a new one
|
||||
func getOrCreateID() string {
|
||||
if id, err := settings.String(keys.Plant); err == nil {
|
||||
return id
|
||||
}
|
||||
|
||||
id := machine.RandomID()
|
||||
settings.SetString(keys.Plant, id)
|
||||
|
||||
return id
|
||||
}
|
||||
|
||||
func Create(machineID string) {
|
||||
// no machine id from config
|
||||
if machineID == "" {
|
||||
if id, err := machine.ProtectedID("evcc-api"); err == nil {
|
||||
// use id from hardware
|
||||
machineID = id
|
||||
} else {
|
||||
// use id from database, generate if needed (e.g. in docker environment)
|
||||
machineID = getOrCreateID()
|
||||
}
|
||||
}
|
||||
|
||||
instanceID = machineID
|
||||
|
||||
if machineID == "" {
|
||||
instanceID = machine.ProtectedID("evcc-api")
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateChargeProgress uploads power and energy data every 30 seconds
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue