Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(orc8r): Update gateway device information during registration #12022

Merged
merged 1 commit into from
Mar 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"magma/orc8r/cloud/go/orc8r"
"magma/orc8r/cloud/go/serdes"
"magma/orc8r/cloud/go/services/bootstrapper"
"magma/orc8r/cloud/go/services/configurator"
"magma/orc8r/cloud/go/services/device"
"magma/orc8r/cloud/go/services/orchestrator/obsidian/models"
"magma/orc8r/cloud/go/services/tenants"
Expand Down Expand Up @@ -44,6 +45,12 @@ func (r *RegistrationService) Register(c context.Context, request *protos.Regist
return clientErr, nil
}

err = updateGatewayDevice(c, deviceInfo, request.Hwid, request.ChallengeKey)
if err != nil {
clientErr := makeErr(fmt.Sprintf("error updating gateway: %v", err))
return clientErr, nil
}

err = r.RegisterDevice(*deviceInfo, request.Hwid, request.ChallengeKey)
if err != nil {
clientErr := makeErr(fmt.Sprintf("error registering device: %v", err))
Expand All @@ -65,11 +72,7 @@ func (r *RegistrationService) Register(c context.Context, request *protos.Regist
}

func RegisterDevice(deviceInfo protos.GatewayDeviceInfo, hwid *protos.AccessGatewayID, challengeKey *protos.ChallengeKey) error {
challengeKeyBase64 := strfmt.Base64(challengeKey.Key)
gatewayRecord := &models.GatewayDevice{
HardwareID: hwid.Id,
Key: &models.ChallengeKey{KeyType: challengeKey.KeyType.String(), Key: &challengeKeyBase64},
}
gatewayRecord := createGatewayDevice(hwid, challengeKey)
err := device.RegisterDevice(context.Background(), deviceInfo.NetworkId, orc8r.AccessGatewayRecordType, hwid.Id, gatewayRecord, serdes.Device)
return err
}
Expand Down Expand Up @@ -114,3 +117,39 @@ func makeErr(errString string) *protos.RegisterResponse {
}
return errRes
}

// createGatewayDevice creates the gateway device model
func createGatewayDevice(hwID *protos.AccessGatewayID, challengeKey *protos.ChallengeKey) *models.GatewayDevice {
challengeKeyBase64 := strfmt.Base64(challengeKey.Key)
return &models.GatewayDevice{
HardwareID: hwID.Id,
Key: &models.ChallengeKey{KeyType: challengeKey.KeyType.String(), Key: &challengeKeyBase64},
}
}

// updateGatewayDevice writes to the device information to the gateway entity
func updateGatewayDevice(ctx context.Context, deviceInfo *protos.GatewayDeviceInfo, hwID *protos.AccessGatewayID, challengeKey *protos.ChallengeKey) error {
networkID := deviceInfo.NetworkId
gatewayID := deviceInfo.LogicalId

ent, err := configurator.LoadEntity(
ctx,
networkID, orc8r.MagmadGatewayType, gatewayID,
configurator.EntityLoadCriteria{},
serdes.Entity,
)
Comment on lines +135 to +140
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's a "load entity by physical ID" func

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the func LoadEntityForPhysicalID gets the entity by the physical ID, but since the gateway is not yet registered to a physical ID, idt it would work... unless there is some load entity by physical ID func u are referencing?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh true you're right, I misread "gateway ID" as meaning "hardware ID" -- a +1 for why functions with large # of arguments is an anti-pattern 🙂

if err != nil {
return err
}

device := createGatewayDevice(hwID, challengeKey)

gw := (&models.MagmadGateway{}).FromBackendModels(ent, device, nil)

_, err = configurator.UpdateEntities(ctx, networkID, gw.ToEntityUpdateCriteria(ent), serdes.Entity)
if err != nil {
return err
}

return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@ import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

"magma/orc8r/cloud/go/orc8r"
"magma/orc8r/cloud/go/serdes"
"magma/orc8r/cloud/go/services/bootstrapper/servicers/registration"
"magma/orc8r/cloud/go/services/configurator"
configuratorTestInit "magma/orc8r/cloud/go/services/configurator/test_init"
"magma/orc8r/cloud/go/services/orchestrator/obsidian/models"
stateTestInit "magma/orc8r/cloud/go/services/state/test_init"
"magma/orc8r/cloud/go/services/tenants"
tenant_protos "magma/orc8r/cloud/go/services/tenants/protos"
tenantsTestInit "magma/orc8r/cloud/go/services/tenants/test_init"
Expand All @@ -33,7 +39,7 @@ var (
registerRequest = &protos.RegisterRequest{
Token: registration.NonceToToken(registration.GenerateNonce(registration.NonceLength)),
Hwid: &protos.AccessGatewayID{
Id: "Id",
Id: hardwareID,
},
ChallengeKey: &protos.ChallengeKey{
KeyType: 0,
Expand All @@ -42,23 +48,27 @@ var (
}
controlProxy = "controlProxy"
nextTenantID int64 = 0
hardwareID = "foo-bar-hardware-id"
)

func TestRegistrationServicer_Register(t *testing.T) {
registrationServicer := setupMockRegistrationServicer()
registrationServicer := setupMockRegistrationServicer(t)

res, err := registrationServicer.Register(context.Background(), registerRequest)
assert.NoError(t, err)

expectedRes := &protos.RegisterResponse{
Response: &protos.RegisterResponse_ControlProxy{ControlProxy: controlProxy},
}
assert.Equal(t, expectedRes, res)

checkRegisteredGateway(t)
}

func TestRegistrationServicer_Register_BadToken(t *testing.T) {
rpcErr := status.Error(codes.NotFound, "errMessage")

registrationServicer := setupMockRegistrationServicer()
registrationServicer := setupMockRegistrationServicer(t)
registrationServicer.GetGatewayDeviceInfo = func(ctx context.Context, token string) (*protos.GatewayDeviceInfo, error) {
return nil, rpcErr
}
Expand All @@ -76,7 +86,7 @@ func TestRegistrationServicer_Register_BadToken(t *testing.T) {
func TestRegistrationServicer_Register_NoControlProxy(t *testing.T) {
rpcErr := status.Error(codes.NotFound, "errMessage")

registrationServicer := setupMockRegistrationServicer()
registrationServicer := setupMockRegistrationServicer(t)
registrationServicer.GetControlProxy = func(networkID string) (string, error) {
return "", rpcErr
}
Expand Down Expand Up @@ -132,7 +142,7 @@ func TestGetControlProxy(t *testing.T) {
assert.Equal(t, controlProxy, res)
}

func setupMockRegistrationServicer() *registration.RegistrationService {
func setupMockRegistrationServicer(t *testing.T) *registration.RegistrationService {
registrationService := &registration.RegistrationService{
GetGatewayDeviceInfo: func(ctx context.Context, token string) (*protos.GatewayDeviceInfo, error) {
return gatewayDeviceInfo, nil
Expand All @@ -145,9 +155,40 @@ func setupMockRegistrationServicer() *registration.RegistrationService {
},
}

stateTestInit.StartTestService(t)
configuratorTestInit.StartTestService(t)

createUnregisteredGateway(t)

return registrationService
}

// createUnregisteredGateway creates an unregistered gateway, i.e. a gateway without its device field
func createUnregisteredGateway(t *testing.T) {
err := configurator.CreateNetwork(context.Background(), configurator.Network{ID: networkID}, serdes.Network)
assert.NoError(t, err)

_, err = configurator.CreateEntities(context.Background(), networkID, []configurator.NetworkEntity{
{
Type: orc8r.MagmadGatewayType,
Key: logicalID,
Config: &models.MagmadGatewayConfigs{},
},
}, serdes.Entity)
assert.NoError(t, err)
}

func checkRegisteredGateway(t *testing.T) {
ent, err := configurator.LoadEntity(
context.Background(),
networkID, orc8r.MagmadGatewayType, logicalID,
configurator.EntityLoadCriteria{},
serdes.Entity,
)
assert.Equal(t, ent.PhysicalID, hardwareID)
assert.NoError(t, err)
}

func setupAddNetworksToTenantsService(t *testing.T) {
var (
tenant1 = &tenant_protos.Tenant{
Expand Down