Newer
Older
"fmt"
Fabian Seidl
committed
"code.fbi.h-da.de/danet/gosdn/controller/customerrs"
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/rbac"
"code.fbi.h-da.de/danet/gosdn/controller/store"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
// DatabaseRoleStore is used to store roles in database.
type DatabaseRoleStore struct {
func NewDatabaseRoleStore(db *mongo.Database) *DatabaseRoleStore {
collection := db.Collection(roleStoreName)
return &DatabaseRoleStore{
collection: collection,
// Add adds a Role.
func (s *DatabaseRoleStore) Add(ctx context.Context, roleToAdd rbac.Role) (err error) {
_, err = s.collection.InsertOne(ctx, roleToAdd)
if err != nil {
if mongo.IsDuplicateKeyError(err) {
return nil
}
Fabian Seidl
committed
return customerrs.CouldNotCreateError{Identifier: roleToAdd.ID(), Type: roleToAdd, Err: err}
}
return nil
}
// Delete deletes a Role.
func (s *DatabaseRoleStore) Delete(ctx context.Context, roleToDelete rbac.Role) (err error) {
_, err = s.collection.DeleteOne(ctx, bson.D{primitive.E{Key: "_id", Value: roleToDelete.ID().String()}})
Fabian Seidl
committed
return customerrs.CouldNotDeleteError{Identifier: roleToDelete.ID(), Type: roleToDelete, Err: err}
}
return nil
}
// Get takes a Roles's UUID or name and returns the Role. If the requested
// Role does not exist an error is returned.
func (s *DatabaseRoleStore) Get(ctx context.Context, query store.Query) (rbac.LoadedRole, error) {
var loadedRole rbac.LoadedRole
if query.ID != uuid.Nil {
Fabian Seidl
committed
return loadedRole, err
}
return loadedRole, nil
}
loadedRole, err := s.getByName(ctx, query.Name)
Fabian Seidl
committed
return loadedRole, err
}
return loadedRole, nil
}
func (s *DatabaseRoleStore) getByID(ctx context.Context, idOfRole uuid.UUID) (loadedRole rbac.LoadedRole, err error) {
result := s.collection.FindOne(ctx, bson.D{primitive.E{Key: "_id", Value: idOfRole.String()}})
Fabian Seidl
committed
return loadedRole, customerrs.CouldNotFindError{ID: idOfRole}
err = result.Decode(&loadedRole)
if err != nil {
log.Printf("Failed marshalling %v", err)
Fabian Seidl
committed
return loadedRole, customerrs.CouldNotMarshallError{Identifier: idOfRole, Type: loadedRole, Err: err}
}
return loadedRole, nil
}
func (s *DatabaseRoleStore) getByName(ctx context.Context, nameOfRole string) (loadedRole rbac.LoadedRole, err error) {
result := s.collection.FindOne(ctx, bson.D{primitive.E{Key: "rolename", Value: nameOfRole}})
Fabian Seidl
committed
return loadedRole, customerrs.CouldNotFindError{Name: nameOfRole}
err = result.Decode(&loadedRole)
if err != nil {
log.Printf("Failed marshalling %v", err)
Fabian Seidl
committed
return loadedRole, customerrs.CouldNotMarshallError{Identifier: nameOfRole, Type: loadedRole, Err: err}
}
return loadedRole, nil
}
// GetAll returns all Roles.
func (s *DatabaseRoleStore) GetAll(ctx context.Context) (loadedRoles []rbac.LoadedRole, err error) {
cursor, err := s.collection.Find(ctx, bson.D{})
if err != nil {
return nil, err
}
defer func() {
if ferr := cursor.Close(ctx); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
err = cursor.All(ctx, &loadedRoles)
if err != nil {
log.Printf("Failed marshalling %v", err)
Fabian Seidl
committed
return nil, customerrs.CouldNotMarshallError{Type: loadedRoles, Err: err}
}
return loadedRoles, nil
}
// Update updates the role.
func (s *DatabaseRoleStore) Update(ctx context.Context, roleToUpdate rbac.Role) (err error) {
var updatedLoadedRole rbac.LoadedRole
update := bson.D{primitive.E{Key: "$set", Value: roleToUpdate}}
upsert := false
after := options.After
opt := options.FindOneAndUpdateOptions{
Upsert: &upsert,
ReturnDocument: &after,
}
err = s.collection.FindOneAndUpdate(
ctx, bson.M{"_id": roleToUpdate.ID().String()}, update, &opt).
Decode(&updatedLoadedRole)
if err != nil {
log.Printf("Could not update Role: %v", err)
Fabian Seidl
committed
return customerrs.CouldNotUpdateError{Identifier: roleToUpdate.ID(), Type: roleToUpdate, Err: err}