Skip to content
Snippets Groups Projects
deviceService.go 3.45 KiB
Newer Older
  • Learn to ignore specific revisions
  • package nucleus
    
    import (
    	"fmt"
    
    	spb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/southbound"
    	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/device"
    	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/southbound"
    	"code.fbi.h-da.de/danet/gosdn/controller/store"
    	"github.com/google/uuid"
    	"github.com/openconfig/ygot/ygot"
    
    	tpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/transport"
    )
    
    // DeviceService provides a device service implementation.
    // This services provides abstraction between the user (e.g a PND) and the matching store (e.g. deviceStore)
    type DeviceService struct {
    	deviceStore device.Store
    	sbiService  southbound.Service
    }
    
    // NewDeviceService creates a device service.
    func NewDeviceService(deviceStore device.Store, sbiService southbound.Service) device.Service {
    	return &DeviceService{
    		deviceStore: deviceStore,
    		sbiService:  sbiService,
    	}
    }
    
    // Get takes a Device's UUID or name and returns the Device.
    func (s *DeviceService) Get(query store.Query) (device.Device, error) {
    	loadedDevice, err := s.deviceStore.Get(query)
    	if err != nil {
    		return nil, err
    	}
    
    	device, err := s.createDeviceFromStore(loadedDevice)
    	if err != nil {
    		return nil, err
    	}
    
    	return device, nil
    }
    
    // GetAll returns all stored devices.
    func (s *DeviceService) GetAll() ([]device.Device, error) {
    	var devices []device.Device
    
    	loadedDevices, err := s.deviceStore.GetAll()
    	if err != nil {
    		return nil, err
    	}
    
    	for _, loadedDevice := range loadedDevices {
    		device, err := s.createDeviceFromStore(loadedDevice)
    		if err != nil {
    			return nil, err
    		}
    
    		devices = append(devices, device)
    	}
    
    	return devices, nil
    }
    
    // Add adds a device to the device store.
    func (s *DeviceService) Add(deviceToAdd device.Device) error {
    	err := s.deviceStore.Add(deviceToAdd)
    	if err != nil {
    		return err
    	}
    
    	return nil
    }
    
    // Update updates a existing device.
    func (s *DeviceService) Update(deviceToUpdate device.Device) error {
    	err := s.deviceStore.Update(deviceToUpdate)
    	if err != nil {
    		return err
    	}
    
    	return nil
    }
    
    // Delete deletes a device from the device store.
    func (s *DeviceService) Delete(deviceToDelete device.Device) error {
    	err := s.deviceStore.Delete(deviceToDelete)
    	if err != nil {
    		return err
    	}
    
    	if deviceToDelete.SBI().Type() == spb.Type_TYPE_PLUGIN {
    		err = s.sbiService.Delete(deviceToDelete.SBI())
    		if err != nil {
    			return err
    		}
    	}
    
    	return nil
    }
    
    func (s *DeviceService) createDeviceFromStore(loadedDevice device.LoadedDevice) (device.Device, error) {
    	if loadedDevice.SBI == "" {
    		return nil, fmt.Errorf("no sbi found for device")
    	}
    
    	sbiForDevice, err := s.sbiService.Get(store.Query{ID: uuid.MustParse(loadedDevice.SBI)})
    	if err != nil {
    		return nil, err
    	}
    
    	d, err := NewDevice(
    		loadedDevice.Name,
    
    		uuid.MustParse(loadedDevice.ID),
    
    		&tpb.TransportOption{
    			Address:  loadedDevice.TransportAddress,
    			Username: loadedDevice.TransportUsername,
    			Password: loadedDevice.TransportPassword,
    			TransportOption: &tpb.TransportOption_GnmiTransportOption{
    				GnmiTransportOption: &tpb.GnmiTransportOption{},
    			},
    			Type: spb.Type_TYPE_OPENCONFIG,
    		}, sbiForDevice)
    	if err != nil {
    		return nil, err
    	}
    
    	// Create 'root' path to be able to load the whole model from the store.
    	path, err := ygot.StringToPath("/", ygot.StructuredPath)
    	if err != nil {
    		return nil, err
    	}
    
    	// Use unmarshall from the devices SBI to unmarshall ygot json in go struct.
    	err = d.SBI().Unmarshal([]byte(loadedDevice.Model), path, d.GetModel())
    	if err != nil {
    		return nil, err
    	}
    
    	return d, nil
    }