add template module

This commit is contained in:
Pascal Fischer
2025-06-12 20:32:18 +02:00
parent 6d5800931e
commit ab2ce57d55
10 changed files with 517 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
package template
import (
"context"
"github.com/netbirdio/management-refactor/internals/shared/db"
)
type Manager interface {
// Create
CreateTemplate(ctx context.Context, tx db.Transaction, template *Template) (*Template, error)
// Read
GetAllTemplates(ctx context.Context, tx db.Transaction, strength db.LockingStrength, accountID string) ([]*Template, error)
GetTemplateByID(ctx context.Context, tx db.Transaction, strength db.LockingStrength, id string) (*Template, error)
// Update
UpdateTemplate(ctx context.Context, tx db.Transaction, template *Template) (*Template, error)
// Delete
DeleteTemplate(ctx context.Context, tx db.Transaction, id string) error
}
+123
View File
@@ -0,0 +1,123 @@
package manager
import (
"encoding/json"
"net/http"
"github.com/gorilla/mux"
"github.com/netbirdio/management-refactor/integrations/shared/api"
nbcontext "github.com/netbirdio/netbird/management/server/context"
"github.com/netbirdio/management-refactor/internals/modules/template"
"github.com/netbirdio/management-refactor/internals/modules/users"
"github.com/netbirdio/management-refactor/internals/shared/db"
"github.com/netbirdio/management-refactor/internals/shared/permissions"
"github.com/netbirdio/management-refactor/internals/shared/permissions/modules"
"github.com/netbirdio/management-refactor/internals/shared/permissions/operations"
)
type handler struct {
manager template.Manager
}
func RegisterEndpoints(router *mux.Router, permissionsManager permissions.Manager, manager template.Manager) {
h := &handler{
manager: manager,
}
router.HandleFunc("/templates", permissionsManager.WithPermission(modules.Template, operations.Write, h.createTemplate)).Methods("POST", "OPTIONS")
router.HandleFunc("/templates", permissionsManager.WithPermission(modules.Template, operations.Read, h.getAllTemplates)).Methods("GET", "OPTIONS")
router.HandleFunc("/templates/{templateId}", permissionsManager.WithPermission(modules.Template, operations.Read, h.getTemplate)).Methods("GET", "OPTIONS")
router.HandleFunc("/templates/{templateId}", permissionsManager.WithPermission(modules.Template, operations.Write, h.updateTemplate)).Methods("PUT", "OPTIONS")
router.HandleFunc("/templates/{templateId}", permissionsManager.WithPermission(modules.Template, operations.Write, h.deleteTemplate)).Methods("DELETE", "OPTIONS")
}
func (h *handler) getAllTemplates(w http.ResponseWriter, r *http.Request, userAuth *nbcontext.UserAuth) {
users, err := h.manager.GetAllTemplates(r.Context(), nil, db.LockingStrengthShare, userAuth.AccountId)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
_ = json.NewEncoder(w).Encode(users)
}
func (h *handler) getTemplate(w http.ResponseWriter, r *http.Request, userAuth *nbcontext.UserAuth) {
vars := mux.Vars(r)
templateId := vars["templateId"]
user, err := h.manager.GetTemplateByID(r.Context(), nil, db.LockingStrengthShare, templateId)
if err != nil {
http.Error(w, "Not Found", http.StatusNotFound)
return
}
_ = json.NewEncoder(w).Encode(user)
}
func (h *handler) createTemplate(w http.ResponseWriter, r *http.Request, userAuth *nbcontext.UserAuth) {
var templateReq api.Template
if err := json.NewDecoder(r.Body).Decode(&templateReq); err != nil {
http.Error(w, "Bad Request", http.StatusBadRequest)
return
}
templateObj := &template.Template{}
templateObj.FromAPIRequest(templateReq)
err := templateObj.Validate()
if err != nil {
http.Error(w, "Bad Request: "+err.Error(), http.StatusBadRequest)
return
}
templateResp, err := h.manager.CreateTemplate(r.Context(), nil, &templateReq)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusCreated)
_ = json.NewEncoder(w).Encode(templateResp)
}
func (h *handler) updateTemplate(w http.ResponseWriter, r *http.Request, userAuth *nbcontext.UserAuth) {
vars := mux.Vars(r)
templateId := vars["templateId"]
var templateReq api.Template
if err := json.NewDecoder(r.Body).Decode(&templateReq); err != nil {
http.Error(w, "Bad Request", http.StatusBadRequest)
return
}
templateObj := &template.Template{}
templateObj.FromAPIRequest(templateReq)
templateObj.Id = templateId
err := templateObj.Validate()
if err != nil {
http.Error(w, "Bad Request: "+err.Error(), http.StatusBadRequest)
return
}
templateResp, err := h.manager.UpdateTemplate(r.Context(), nil, &templateReq)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
_ = json.NewEncoder(w).Encode(templateResp)
}
func (h *handler) deleteTemplate(w http.ResponseWriter, r *http.Request, userAuth *nbcontext.UserAuth) {
vars := mux.Vars(r)
templateId := vars["templateId"]
err := h.manager.DeleteTemplate(r.Context(), nil, templateId)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusNoContent)
}
@@ -0,0 +1 @@
package manager
@@ -0,0 +1,41 @@
package manager
//go:generate go run github.com/golang/mock/mockgen -package manager -destination=manager_mock.go -source=../interface.go -build_flags=-mod=mod
import (
"context"
"github.com/netbirdio/management-refactor/internals/modules/template"
"github.com/netbirdio/management-refactor/internals/shared/db"
)
var _ template.Manager = (*Manager)(nil)
type Manager struct {
repo Repository
}
func NewManager(repo Repository) *Manager {
return &Manager{repo: repo}
}
func (m *Manager) CreateTemplate(ctx context.Context, tx db.Transaction, template *template.Template) (*template.Template, error) {
return m.repo.CreateTemplate(ctx, tx, template)
}
func (m *Manager) GetAllTemplates(ctx context.Context, tx db.Transaction, strength db.LockingStrength, accountID string) ([]*template.Template, error) {
return m.repo.GetAllTemplates(ctx, tx, strength, accountID)
}
func (m *Manager) GetTemplateByID(ctx context.Context, tx db.Transaction, strength db.LockingStrength, id string) (*template.Template, error) {
return m.repo.GetTemplateByID(ctx, tx, strength, id)
}
func (m *Manager) UpdateTemplate(ctx context.Context, tx db.Transaction, template *template.Template) (*template.Template, error) {
return m.repo.UpdateTemplate(ctx, tx, template)
}
func (m *Manager) DeleteTemplate(ctx context.Context, tx db.Transaction, id string) error {
template := &template.Template{Id: id}
return m.repo.DeleteTemplate(ctx, tx, template)
}
@@ -0,0 +1,111 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: ../interface.go
// Package manager is a generated GoMock package.
package manager
import (
context "context"
reflect "reflect"
gomock "github.com/golang/mock/gomock"
template "github.com/netbirdio/management-refactor/internals/modules/template"
db "github.com/netbirdio/management-refactor/internals/shared/db"
)
// MockManager is a mock of Manager interface.
type MockManager struct {
ctrl *gomock.Controller
recorder *MockManagerMockRecorder
}
// MockManagerMockRecorder is the mock recorder for MockManager.
type MockManagerMockRecorder struct {
mock *MockManager
}
// NewMockManager creates a new mock instance.
func NewMockManager(ctrl *gomock.Controller) *MockManager {
mock := &MockManager{ctrl: ctrl}
mock.recorder = &MockManagerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockManager) EXPECT() *MockManagerMockRecorder {
return m.recorder
}
// CreateTemplate mocks base method.
func (m *MockManager) CreateTemplate(ctx context.Context, tx db.Transaction, template *template.Template) (*template.Template, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CreateTemplate", ctx, tx, template)
ret0, _ := ret[0].(*template.Template)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// CreateTemplate indicates an expected call of CreateTemplate.
func (mr *MockManagerMockRecorder) CreateTemplate(ctx, tx, template interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTemplate", reflect.TypeOf((*MockManager)(nil).CreateTemplate), ctx, tx, template)
}
// DeleteTemplate mocks base method.
func (m *MockManager) DeleteTemplate(ctx context.Context, tx db.Transaction, id string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteTemplate", ctx, tx, id)
ret0, _ := ret[0].(error)
return ret0
}
// DeleteTemplate indicates an expected call of DeleteTemplate.
func (mr *MockManagerMockRecorder) DeleteTemplate(ctx, tx, id interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTemplate", reflect.TypeOf((*MockManager)(nil).DeleteTemplate), ctx, tx, id)
}
// GetAllTemplates mocks base method.
func (m *MockManager) GetAllTemplates(ctx context.Context, tx db.Transaction, strength db.LockingStrength, accountID string) ([]*template.Template, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetAllTemplates", ctx, tx, strength, accountID)
ret0, _ := ret[0].([]*template.Template)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAllTemplates indicates an expected call of GetAllTemplates.
func (mr *MockManagerMockRecorder) GetAllTemplates(ctx, tx, strength, accountID interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllTemplates", reflect.TypeOf((*MockManager)(nil).GetAllTemplates), ctx, tx, strength, accountID)
}
// GetTemplateByID mocks base method.
func (m *MockManager) GetTemplateByID(ctx context.Context, tx db.Transaction, strength db.LockingStrength, id string) (*template.Template, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetTemplateByID", ctx, tx, strength, id)
ret0, _ := ret[0].(*template.Template)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetTemplateByID indicates an expected call of GetTemplateByID.
func (mr *MockManagerMockRecorder) GetTemplateByID(ctx, tx, strength, id interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTemplateByID", reflect.TypeOf((*MockManager)(nil).GetTemplateByID), ctx, tx, strength, id)
}
// UpdateTemplate mocks base method.
func (m *MockManager) UpdateTemplate(ctx context.Context, tx db.Transaction, template *template.Template) (*template.Template, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateTemplate", ctx, tx, template)
ret0, _ := ret[0].(*template.Template)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpdateTemplate indicates an expected call of UpdateTemplate.
func (mr *MockManagerMockRecorder) UpdateTemplate(ctx, tx, template interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTemplate", reflect.TypeOf((*MockManager)(nil).UpdateTemplate), ctx, tx, template)
}
@@ -0,0 +1 @@
package manager
@@ -0,0 +1,61 @@
package manager
//go:generate go run github.com/golang/mock/mockgen -package manager -destination=repository_mock.go -source=./repository.go -build_flags=-mod=mod
import (
"context"
log "github.com/sirupsen/logrus"
"github.com/netbirdio/management-refactor/internals/modules/template"
"github.com/netbirdio/management-refactor/internals/shared/db"
)
var _ Repository = (*repository)(nil)
type Repository interface {
RunInTx(fn func(tx db.Transaction) error) error
CreateTemplate(ctx context.Context, tx db.Transaction, template *template.Template) (*template.Template, error)
GetAllTemplates(ctx context.Context, tx db.Transaction, strength db.LockingStrength, accountId string) ([]*template.Template, error)
GetTemplateByID(ctx context.Context, tx db.Transaction, strength db.LockingStrength, id string) (*template.Template, error)
UpdateTemplate(ctx context.Context, tx db.Transaction, template *template.Template) (*template.Template, error)
DeleteTemplate(ctx context.Context, tx db.Transaction, template *template.Template) error
}
type repository struct {
store *db.Store
}
func NewRepository(s *db.Store) Repository {
err := s.AutoMigrate(template.Template{})
if err != nil {
log.Fatalf("Failed to auto migrate: %v", err)
}
return &repository{store: s}
}
func (r *repository) RunInTx(fn func(tx db.Transaction) error) error {
return r.store.RunInTx(fn)
}
func (r *repository) CreateTemplate(ctx context.Context, tx db.Transaction, template *template.Template) (*template.Template, error) {
return template, r.store.Create(tx, template)
}
func (r *repository) GetAllTemplates(ctx context.Context, tx db.Transaction, strength db.LockingStrength, accountId string) (templates []*template.Template, err error) {
err = r.store.GetMany(tx, strength, templates, "account_id = ?", accountId)
return
}
func (r *repository) GetTemplateByID(ctx context.Context, tx db.Transaction, strength db.LockingStrength, id string) (template *template.Template, err error) {
err = r.store.GetOne(tx, strength, &template, "id = ?", id)
return
}
func (r *repository) UpdateTemplate(ctx context.Context, tx db.Transaction, template *template.Template) (*template.Template, error) {
return template, r.store.Update(tx, template)
}
func (r *repository) DeleteTemplate(ctx context.Context, tx db.Transaction, template *template.Template) error {
return r.store.Delete(tx, template)
}
@@ -0,0 +1,125 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: ./repository.go
// Package manager is a generated GoMock package.
package manager
import (
context "context"
reflect "reflect"
gomock "github.com/golang/mock/gomock"
template "github.com/netbirdio/management-refactor/internals/modules/template"
db "github.com/netbirdio/management-refactor/internals/shared/db"
)
// MockRepository is a mock of Repository interface.
type MockRepository struct {
ctrl *gomock.Controller
recorder *MockRepositoryMockRecorder
}
// MockRepositoryMockRecorder is the mock recorder for MockRepository.
type MockRepositoryMockRecorder struct {
mock *MockRepository
}
// NewMockRepository creates a new mock instance.
func NewMockRepository(ctrl *gomock.Controller) *MockRepository {
mock := &MockRepository{ctrl: ctrl}
mock.recorder = &MockRepositoryMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder {
return m.recorder
}
// CreateTemplate mocks base method.
func (m *MockRepository) CreateTemplate(ctx context.Context, tx db.Transaction, template *template.Template) (*template.Template, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CreateTemplate", ctx, tx, template)
ret0, _ := ret[0].(*template.Template)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// CreateTemplate indicates an expected call of CreateTemplate.
func (mr *MockRepositoryMockRecorder) CreateTemplate(ctx, tx, template interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTemplate", reflect.TypeOf((*MockRepository)(nil).CreateTemplate), ctx, tx, template)
}
// DeleteTemplate mocks base method.
func (m *MockRepository) DeleteTemplate(ctx context.Context, tx db.Transaction, template *template.Template) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteTemplate", ctx, tx, template)
ret0, _ := ret[0].(error)
return ret0
}
// DeleteTemplate indicates an expected call of DeleteTemplate.
func (mr *MockRepositoryMockRecorder) DeleteTemplate(ctx, tx, template interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTemplate", reflect.TypeOf((*MockRepository)(nil).DeleteTemplate), ctx, tx, template)
}
// GetAllTemplates mocks base method.
func (m *MockRepository) GetAllTemplates(ctx context.Context, tx db.Transaction, strength db.LockingStrength, accountId string) ([]*template.Template, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetAllTemplates", ctx, tx, strength, accountId)
ret0, _ := ret[0].([]*template.Template)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAllTemplates indicates an expected call of GetAllTemplates.
func (mr *MockRepositoryMockRecorder) GetAllTemplates(ctx, tx, strength, accountId interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllTemplates", reflect.TypeOf((*MockRepository)(nil).GetAllTemplates), ctx, tx, strength, accountId)
}
// GetTemplateByID mocks base method.
func (m *MockRepository) GetTemplateByID(ctx context.Context, tx db.Transaction, strength db.LockingStrength, id string) (*template.Template, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetTemplateByID", ctx, tx, strength, id)
ret0, _ := ret[0].(*template.Template)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetTemplateByID indicates an expected call of GetTemplateByID.
func (mr *MockRepositoryMockRecorder) GetTemplateByID(ctx, tx, strength, id interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTemplateByID", reflect.TypeOf((*MockRepository)(nil).GetTemplateByID), ctx, tx, strength, id)
}
// RunInTx mocks base method.
func (m *MockRepository) RunInTx(fn func(db.Transaction) error) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RunInTx", fn)
ret0, _ := ret[0].(error)
return ret0
}
// RunInTx indicates an expected call of RunInTx.
func (mr *MockRepositoryMockRecorder) RunInTx(fn interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RunInTx", reflect.TypeOf((*MockRepository)(nil).RunInTx), fn)
}
// UpdateTemplate mocks base method.
func (m *MockRepository) UpdateTemplate(ctx context.Context, tx db.Transaction, template *template.Template) (*template.Template, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateTemplate", ctx, tx, template)
ret0, _ := ret[0].(*template.Template)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpdateTemplate indicates an expected call of UpdateTemplate.
func (mr *MockRepositoryMockRecorder) UpdateTemplate(ctx, tx, template interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTemplate", reflect.TypeOf((*MockRepository)(nil).UpdateTemplate), ctx, tx, template)
}
@@ -0,0 +1 @@
package manager
+31
View File
@@ -0,0 +1,31 @@
package template
import (
"github.com/netbirdio/netbird/management/server/http/api"
)
type Template struct {
Id string `gorm:"primary_key"`
}
// NewTemplate creates a new Template object
func NewTemplate() *Template {
return &Template{}
}
// Copy the Template object
func (u *Template) Copy() *Template {
return &Template{}
}
func (u *Template) ToApiResponse() *api.Template {
}
func (n *Template) FromAPIRequest(req *api.Template) {
}
func (n *Template) Validate() error {
return nil
}