diff --git a/internal/app/migrations/20260820000000_migrate_device_mode.down.sql b/internal/app/migrations/20260820000000_migrate_device_mode.down.sql new file mode 100644 index 000000000..0d19079f1 --- /dev/null +++ b/internal/app/migrations/20260820000000_migrate_device_mode.down.sql @@ -0,0 +1,6 @@ +/********************************************************************* +* Copyright (c) Intel Corporation 2026 +* SPDX-License-Identifier: Apache-2.0 +**********************************************************************/ + +ALTER TABLE devices DROP COLUMN currentmode; diff --git a/internal/app/migrations/20260820000000_migrate_device_mode.up.sql b/internal/app/migrations/20260820000000_migrate_device_mode.up.sql new file mode 100644 index 000000000..17c6fd793 --- /dev/null +++ b/internal/app/migrations/20260820000000_migrate_device_mode.up.sql @@ -0,0 +1,6 @@ +/********************************************************************* +* Copyright (c) Intel Corporation 2026 +* SPDX-License-Identifier: Apache-2.0 +**********************************************************************/ + +ALTER TABLE devices ADD COLUMN currentmode TEXT; diff --git a/internal/entity/device.go b/internal/entity/device.go index 6baa9cea2..17e1e77be 100644 --- a/internal/entity/device.go +++ b/internal/entity/device.go @@ -25,6 +25,8 @@ type Device struct { UseTLS bool `bson:"usetls"` AllowSelfSigned bool `bson:"allowselfsigned"` CertHash *string `bson:"certhash"` + // Queryable mirror of the deviceinfo currentMode JSON field, synced on every insert/update. + CurrentMode string `bson:"currentmode"` } type Explorer struct { diff --git a/internal/usecase/devices/usecase.go b/internal/usecase/devices/usecase.go index 711a39dc4..8a4e90c78 100644 --- a/internal/usecase/devices/usecase.go +++ b/internal/usecase/devices/usecase.go @@ -103,6 +103,11 @@ func (uc *UseCase) dtoToEntity(d *dto.Device) (*entity.Device, error) { AllowSelfSigned: d.AllowSelfSigned, } + // Sync the queryable mirror column from the deviceinfo blob (source of truth). + if d.DeviceInfo != nil { + d1.CurrentMode = d.DeviceInfo.CurrentMode + } + d1.Password, err = uc.safeRequirements.Encrypt(d1.Password) if err != nil { return nil, ErrDeviceUseCase.Wrap("dtoToEntity", "failed to encrypt password", err) diff --git a/internal/usecase/nosqldb/mongo/device.go b/internal/usecase/nosqldb/mongo/device.go index c1e5a45f3..183ea7c6f 100644 --- a/internal/usecase/nosqldb/mongo/device.go +++ b/internal/usecase/nosqldb/mongo/device.go @@ -42,6 +42,7 @@ type deviceUpdateFields struct { UseTLS bool `bson:"usetls"` AllowSelfSigned bool `bson:"allowselfsigned"` CertHash *string `bson:"certhash"` + CurrentMode string `bson:"currentmode"` } type deviceUpdateDocument struct { @@ -247,6 +248,7 @@ func (r *DeviceRepo) Update(ctx context.Context, d *entity.Device) (bool, error) UseTLS: d.UseTLS, AllowSelfSigned: d.AllowSelfSigned, CertHash: d.CertHash, + CurrentMode: d.CurrentMode, }}, ) if err != nil { diff --git a/internal/usecase/sqldb/device.go b/internal/usecase/sqldb/device.go index 7766d3523..d8fa3d4a2 100644 --- a/internal/usecase/sqldb/device.go +++ b/internal/usecase/sqldb/device.go @@ -348,6 +348,7 @@ func (r *DeviceRepo) Update(_ context.Context, d *entity.Device) (bool, error) { Set("useTLS", d.UseTLS). Set("allowSelfSigned", d.AllowSelfSigned). Set("certhash", d.CertHash). + Set("currentmode", d.CurrentMode). Where("guid = ? AND tenantid = ?", d.GUID, d.TenantID). ToSql() if err != nil { @@ -420,8 +421,8 @@ func (r *DeviceRepo) UpdateLastSeen(_ context.Context, guid string) error { func (r *DeviceRepo) Insert(_ context.Context, d *entity.Device) (string, error) { insertBuilder := r.Builder. Insert("devices"). - Columns("guid", "hostname", "tags", "mpsinstance", "connectionstatus", "mpsusername", "tenantid", "friendlyname", "dnssuffix", "deviceinfo", "username", "password", "mpspassword", "mebxpassword", "usetls", "allowselfsigned", "certhash"). - Values(d.GUID, d.Hostname, d.Tags, d.MPSInstance, d.ConnectionStatus, d.MPSUsername, d.TenantID, d.FriendlyName, d.DNSSuffix, d.DeviceInfo, d.Username, d.Password, d.MPSPassword, d.MEBXPassword, d.UseTLS, d.AllowSelfSigned, d.CertHash) + Columns("guid", "hostname", "tags", "mpsinstance", "connectionstatus", "mpsusername", "tenantid", "friendlyname", "dnssuffix", "deviceinfo", "username", "password", "mpspassword", "mebxpassword", "usetls", "allowselfsigned", "certhash", "currentmode"). + Values(d.GUID, d.Hostname, d.Tags, d.MPSInstance, d.ConnectionStatus, d.MPSUsername, d.TenantID, d.FriendlyName, d.DNSSuffix, d.DeviceInfo, d.Username, d.Password, d.MPSPassword, d.MEBXPassword, d.UseTLS, d.AllowSelfSigned, d.CertHash, d.CurrentMode) if !r.IsEmbedded { insertBuilder = insertBuilder.Suffix("RETURNING xmin::text") diff --git a/internal/usecase/sqldb/device_test.go b/internal/usecase/sqldb/device_test.go index 67d7d806e..214907133 100644 --- a/internal/usecase/sqldb/device_test.go +++ b/internal/usecase/sqldb/device_test.go @@ -49,6 +49,7 @@ func setupDeviceTable(t *testing.T) *sql.DB { usetls BOOLEAN NOT NULL DEFAULT FALSE, allowselfsigned BOOLEAN NOT NULL DEFAULT FALSE, certhash TEXT NOT NULL DEFAULT '', + currentmode TEXT, lastconnected TEXT, lastdisconnected TEXT, lastseen TEXT @@ -815,7 +816,8 @@ func TestDeviceRepo_Update(t *testing.T) { mebxpassword TEXT, usetls BOOLEAN NOT NULL DEFAULT FALSE, allowselfsigned BOOLEAN NOT NULL DEFAULT FALSE, - certhash TEXT NOT NULL DEFAULT '' + certhash TEXT NOT NULL DEFAULT '', + currentmode TEXT ); `) require.NoError(t, err)