Skip to content
Snippets Groups Projects
Select Git revision
  • abed21dac884f16179a70a06b95d1ff42408a437
  • master default
  • ui-handover
  • ui-update-yang
  • inventory-manager-netbox
  • heiss_bachelor_thesis
  • proto-getters
  • 392-remove-renovate
  • renovate/go.mongodb.org-mongo-driver-2.x
  • renovate/github.com-bufbuild-protovalidate-go-0.x
  • renovate/google.golang.org-genproto-googleapis-api-digest
  • renovate/github.com-prometheus-client_golang-1.x
  • renovate/eslint-9.x-lockfile
  • renovate/eslint-plugin-react-7.x-lockfile
  • renovate/dompurify-3.x-lockfile
  • renovate/testing-library-react-16.x-lockfile
  • renovate/eslint-plugin-prettier-5.x-lockfile
  • renovate/react-dom-18.x-lockfile
  • renovate/eslint-plugin-react-hooks-5.x-lockfile
  • renovate/testing-library-user-event-14.x-lockfile
  • renovate/reduxjs-toolkit-2.x-lockfile
  • renovate/github.com-openconfig-gnmi-0.x
  • 0.1.0
23 results

pndStore.go

Blame
  • user avatar
    Malte Bauch authored
    9f4240a4
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    pndStore.go 4.43 KiB
    package store
    
    import (
    	"encoding/json"
    	"fmt"
    	"io/ioutil"
    	"reflect"
    
    	tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport"
    	"code.fbi.h-da.de/danet/gosdn/interfaces/networkdomain"
    	"code.fbi.h-da.de/danet/gosdn/interfaces/store"
    	"code.fbi.h-da.de/danet/gosdn/nucleus/errors"
    	"github.com/google/uuid"
    	log "github.com/sirupsen/logrus"
    )
    
    // DeviceDetails contains details of a device used by the cSBI mechanism
    type DeviceDetails struct {
    	ID              string
    	Address         string
    	TransportOption *tpb.TransportOption
    }
    
    // PndStore is used to store PrincipalNetworkDomains
    type PndStore struct {
    	pndStoreName    string
    	pendingChannels map[uuid.UUID]chan DeviceDetails
    	*genericStore
    }
    
    // NewPndStore returns a PndStore
    func NewPndStore() *PndStore {
    	return &PndStore{
    		genericStore:    newGenericStore(),
    		pendingChannels: make(map[uuid.UUID]chan DeviceDetails),
    		pndStoreName:    "pnd-store.json"}
    }
    
    // GetPND takes a PrincipalNetworkDomain's UUID and returns the PrincipalNetworkDomain. If the requested
    // PrincipalNetworkDomain does not exist an error is returned.
    func (s *PndStore) GetPND(id uuid.UUID) (networkdomain.NetworkDomain, error) {
    	item, err := s.genericStore.Get(id)
    	if err != nil {
    		return nil, err
    	}
    	pnd, ok := item.(networkdomain.NetworkDomain)
    	if !ok {
    		return nil, &errors.ErrInvalidTypeAssertion{
    			Value: pnd,
    			Type:  (*networkdomain.NetworkDomain)(nil),
    		}
    	}
    	log.WithFields(log.Fields{
    		"uuid": id,
    	}).Debug("principal network domain was accessed")
    	return pnd, nil
    }
    
    // Add adds a device to the device store.
    // It also adds the name of the device to the lookup table.
    func (s *PndStore) Add(item store.Storable) error {
    	if s.Exists(item.ID()) {
    		return &errors.ErrAlreadyExists{Item: item}
    	}
    
    	s.storeLock.Lock()
    	s.genericStore.Store[item.ID()] = item
    	s.storeLock.Unlock()
    
    	log.WithFields(log.Fields{
    		"type": reflect.TypeOf(item),
    		"uuid": item.ID(),
    	}).Debug("storable was added")
    
    	err := s.persist(item)
    	if err != nil {
    		return err
    	}
    
    	return nil
    }
    
    // PendingChannels holds channels used communicate with pending
    // cSBI deployments
    func (s *PndStore) PendingChannels(id uuid.UUID, parseErrors ...error) (chan DeviceDetails, error) {
    	ch, ok := s.pendingChannels[id]
    	if !ok {
    		return nil, &errors.ErrNotFound{ID: id}
    	}
    	return ch, nil
    }
    
    // AddPendingChannel adds a pending channel to the map
    func (s *PndStore) AddPendingChannel(id uuid.UUID, ch chan DeviceDetails) {
    	s.pendingChannels[id] = ch
    }
    
    // RemovePendingChannel removes a pending channel from the map
    func (s *PndStore) RemovePendingChannel(id uuid.UUID) {
    	delete(s.pendingChannels, id)
    }
    
    func (s *PndStore) persist(item store.Storable) error {
    	ensureFilesystemStorePathExists(s.pndStoreName)
    
    	_, ok := item.(networkdomain.NetworkDomain)
    	if !ok {
    		return fmt.Errorf("item is no NetworkDoman. got=%T", item)
    	}
    
    	var networkDomainsToPersist []LoadedPnd
    
    	for _, value := range s.genericStore.Store {
    		networkDomain, ok := value.(networkdomain.NetworkDomain)
    		if !ok {
    			return fmt.Errorf("item is no Device. got=%T", item)
    		}
    		networkDomainsToPersist = append(networkDomainsToPersist, LoadedPnd{
    			Name:        networkDomain.GetName(),
    			Description: networkDomain.GetDescription(),
    			ID:          networkDomain.ID(),
    		})
    	}
    
    	storeDataAsJSON, err := json.MarshalIndent(networkDomainsToPersist, "", " ")
    	if err != nil {
    		return err
    	}
    
    	err = ioutil.WriteFile(getCompletePathToFileStore(s.pndStoreName), storeDataAsJSON, 0644)
    	if err != nil {
    		return err
    	}
    
    	return nil
    }
    
    // LoadedPnd represents a Principal Network Domain that was loaeded by using
    // the Load() method of the PndStore.
    type LoadedPnd struct {
    	ID          uuid.UUID `json:"id,omitempty"`
    	Name        string    `json:"name,omitempty"`
    	Description string    `json:"description,omitempty"`
    }
    
    // Load unmarshals the contents of the storage file associated with a PndStore
    // and returns it as []LoadedPnd.
    func (s *PndStore) Load() ([]LoadedPnd, error) {
    	var loadedNetworkDomains []LoadedPnd
    
    	err := ensureFilesystemStorePathExists(s.pndStoreName)
    	if err != nil {
    		log.Debug(fmt.Printf("Err: %+v\n", err))
    		return loadedNetworkDomains, err
    	}
    
    	dat, err := ioutil.ReadFile(getCompletePathToFileStore(s.pndStoreName))
    	if err != nil {
    		log.Debug(fmt.Printf("Err: %+v\n", err))
    		return loadedNetworkDomains, err
    	}
    
    	err = json.Unmarshal(dat, &loadedNetworkDomains)
    	if err != nil {
    		log.Debug(fmt.Printf("Err: %+v\n", err))
    		return loadedNetworkDomains, err
    	}
    
    	return loadedNetworkDomains, nil
    }